REV.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:
Windows编程
开发平台:
Visual C++
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Copyright (C) 1993-1997 Microsoft Corporation. All Rights Reserved.
- //
- // PROGRAM: Rev.c
- //
- // PURPOSE: Helper functions for Reversi Sample Game
- //
- // FUNCTIONS:
- // finalscore() - Calculate final score
- // legalcheck() - Return 1 if move legal, else return 0
- // makemove() - Capture enemy pieces
- // score() - Calculate the value of board
- // minmax() - Play human move then recursively play computer move
- //
- // SPECIAL INSTRUCTIONS: N/A
- //
- #include <windows.h>
- #include <windowsx.h>
- #include <process.h>
- #include <stdlib.h>
- #include "reversi.h"
- // declarations of function in reversi.c
- VOID NEAR PASCAL paintmove(BYTE b[BoardSize], INT move, INT friendly,
- INT enemy);
- // variable declarations
- extern INT moves[61];
- extern INT BestMove[max_depth+2];
- extern HWND hWin;
- extern HDC hDisp;
- extern INT depth;
- extern INT direc[];
- // Indexes for computing scores and whether or not a player has
- // any pieces on the board. Very order dependant.
- BYTE PieceFlags[] = { 0x00 , // Ignore sides
- 0x00 , // Ignore blanks
- 0x01 , // Human has a piece
- 0x02 , // Computer has a piece
- };
- //
- // The scoring tables are used to evaluate the board
- // position. The corners of the board change value
- // according to whether a given square is occupied or
- // not. This can be done dynamically, saving ~ 1K
- // worth of data space but costing an as of yet
- // undetermined performance hit.
- //
- #define B11 11 // Offsets to particular squares
- #define B18 18
- #define B81 81
- #define B88 88
- #define maskb11 0x08 // Masks used for indexing into Scoring tables.
- #define maskb18 0x04
- #define maskb81 0x02
- #define maskb88 0x01
- //
- // FUNCTION: finalscore()
- //
- // PURPOSE: Calculate final score
- //
- INT NEAR PASCAL finalscore(
- BYTE b[],
- BYTE friendly,
- BYTE enemy)
- {
- INT i;
- INT count=0;
- for (i=11 ; i<=88 ; i++) {
- if (b[i] == friendly)
- count++;
- else
- if (b[i] == enemy)
- count--;
- }
- if (count > 0)
- return(win + count);
- else
- if (count < 0)
- return(loss + count);
- else
- return(0);
- }
- //
- // FUNCTION: legalcheck()
- //
- // PURPOSE: Return 1 if move legal, else return 0
- //
- INT NEAR PASCAL legalcheck(
- BYTE b[],
- INT move,
- BYTE friendly,
- BYTE enemy)
- {
- INT sq,d;
- INT *p;
- if (b[move] == empty) {
- p=direc;
- while ((d = *p++) != 0) {
- sq=move;
- if (b[sq += d] == enemy) {
- while(b[sq += d] == enemy)
- ;
- if (b[sq] == friendly) return(1);
- }
- }
- }
- return(0);
- }
- //
- // FUNCTION: makemove()
- //
- // PURPOSE: Capture enemy pieces
- //
- VOID NEAR PASCAL makemove(
- BYTE b[],
- INT move,
- BYTE friendly,
- BYTE enemy)
- {
- INT sq,d;
- INT *p;
- if (move != PASS) {
- p=direc;
- while ((d = *p++) != 0) {
- sq=move;
- if (b[sq += d] == enemy) {
- while(b[sq += d] == enemy)
- ;
- if (b[sq] == friendly)
- while(b[sq -= d] == enemy)
- b[sq]=friendly;
- }
- }
- b[move]=friendly;
- }
- }
- //
- // FUNCTION: score()
- //
- // PURPOSE: Calculate the value of board
- //
- INT NEAR PASCAL score(
- BYTE b[],
- BYTE friendly,
- BYTE enemy)
- {
- INT *pvalue;
- BYTE *pb;
- INT fpoints=0;
- INT epoints=0;
- INT ecount=0;
- BYTE bv;
- INT v,b11,b18,b81,b88;
- static INT value[79] = { 99, -8, 8, 6, 6, 8, -8, 99,000,
- 000, -8,-24, -4, -3, -3, -4,-24, -8,000,
- 000, 8, -4, 7, 4, 4, 7, -4, 8,000,
- 000, 6, -3, 4, 0, 0, 4, -3, 6,000,
- 000, 6, -3, 4, 0, 0, 4, -3, 6,000,
- 000, 8, -4, 7, 4, 4, 7, -4, 8,000,
- 000, -8,-24, -4, -3, -3, -4,-24, -8,000,
- 000, 99, -8, 8, 6, 6, 8, -8, 99,infin};
- static INT value2[79]= { 99, -8, 8, 6, 6, 8, -8, 99,000,
- 000, -8,-24, 0, 1, 1, 0,-24, -8,000,
- 000, 8, 0, 7, 4, 4, 7, 0, 8,000,
- 000, 6, 1, 4, 1, 1, 4, 1, 6,000,
- 000, 6, 1, 4, 1, 1, 4, 1, 6,000,
- 000, 8, 0, 7, 4, 4, 7, 0, 8,000,
- 000, -8,-24, 0, 1, 1, 1,-24, -8,000,
- 000, 99, -8, 8, 6, 6, 8, -8, 99,infin};
- pb = &b[11];
- b11 = *pb;
- b18 = b[18];
- b81 = b[81];
- b88 = b[88];
- if ((b11 != empty) || (b18 != empty) || (b81 != empty) || (b88 != empty)) {
- pvalue = value2;
- if (b11 == empty) {
- value2[12-11] = -8; value2[21-11] = -8; value2[22-11] = -24;
- } else {
- value2[12-11] = 12; value2[21-11] = 12; value2[22-11] = 8;
- }
- if (b18 == empty) {
- value2[17-11] = -8; value2[28-11] = -8; value2[27-11] = -24;
- } else {
- value2[17-11] = 12; value2[28-11] = 12; value2[27-11] = 8;
- }
- if (b81 == empty) {
- value2[82-11] = -8; value2[71-11] = -8; value2[72-11] = -24;
- } else {
- value2[82-11] = 12; value2[71-11] = 12; value2[72-11] = 8;
- }
- if (b88 == empty) {
- value2[87-11] = -8; value2[78-11] = -8; value2[77-11] = -24;
- } else {
- value2[87-11] = 12; value2[78-11] = 12; value2[77-11] = 8;
- }
- } else {
- pvalue = value;
- }
- while((v=*pvalue++) != infin) {
- bv = *pb++;
- if (bv == friendly)
- fpoints += v;
- else if (bv == enemy) {
- epoints += v;
- ecount++;
- }
- }
- if (!ecount) // any enemy pieces on the board?
- return(win); // if not, we just won!
- else
- return(fpoints-epoints);
- }
- //
- // FUNCTION: minmax()
- //
- // PURPOSE: Play human move then recursively play computer move
- //
- INT NEAR PASCAL minmax(
- BYTE b[max_depth + 2][100],
- INT move,
- BYTE friendly,
- BYTE enemy,
- INT ply,
- INT vmin,
- INT vmax)
- {
- BYTE *pCurrent, *pPrevious, *pSource, *pDest;
- INT *pMoves;
- INT *pBestMove;
- INT i;
- INT sq, value, cur_move;
- INT count=0; // not used !
- pPrevious = &b[ply][0];
- pCurrent = &b[ply+1][0];
- pSource = &b[ply][11];
- pDest = &b[ply+1][11];
- for (i=11 ; i<=88 ; i++) *pDest++=*pSource++;
- pBestMove = &BestMove[ply];
- if (move == PASS) {
- if (ply == depth) {
- pMoves = moves;
- while((sq = *pMoves++) != 0) {
- if (legalcheck(pCurrent,sq,enemy,friendly))
- return(score(pCurrent,friendly,enemy));
- }
- return(finalscore(pCurrent,friendly,enemy));
- }
- }
- else {
- if (ply == 0) {
- hDisp = GetDC(hWin);
- paintmove(pCurrent,move,friendly,enemy);
- ReleaseDC(hWin, hDisp);
- }
- else {
- makemove(pCurrent,move,friendly,enemy);
- if (ply == depth) return(score(pCurrent,friendly,enemy));
- }
- }
- pMoves = moves;
- cur_move = PASS;
- *pBestMove = PASS;
- while((sq = *pMoves++) != 0) {
- if (legalcheck(pCurrent,sq,enemy,friendly)) {
- cur_move = sq;
- value = minmax(b,cur_move,enemy,friendly,ply+1,-vmax,-vmin);
- if (value > vmin) {
- vmin = value;
- *pBestMove = cur_move;
- if (value >= vmax) goto cutoff; // alpha-beta cutoff
- }
- }
- }
- if (cur_move == PASS) {
- if (move == PASS) // two passes in a row mean game is over
- return(finalscore(pCurrent,friendly,enemy));
- else {
- value = minmax(b,PASS,enemy,friendly,ply+1,-vmax,-vmin);
- if (value > vmin) vmin = value;
- }
- }
- cutoff:
- return(-vmin);
- }