# 8.5 趣味游戏(2)

8-26 shuffle.c

``` 1 #include <stdio.h>
2 typedef struct card
3 {
4    int Suit;    //花色
5    char Number;    //牌数
6 }Card;
7 Card card1[52];    //保存每张扑克的花色、数字
8 void ShowCard(); //显示牌
9 void Shuffle(); //洗牌
10 int main()
11 {
12    int i, suit1, temp;
13    suit1 = 2;
14    for (i = 0; i < 52; i++)    //生成52张牌
15    {
16       if (i % 13 == 0)
17          suit1++;    //改变花色
18       card1[i].Suit = suit1;    //保存花色
19       temp = i % 13;
20       if (temp == 0)
21          card1[i].Number = ‘A‘;
22       else if (temp == 9)
23          card1[i].Number = ‘0‘;
24       else if (temp == 10)
25          card1[i].Number = ‘J‘;
26       else if (temp == 11)
27          card1[i].Number = ‘Q‘;
28       else if (temp == 12)
29          card1[i].Number = ‘K‘;
30       else
31          card1[i].Number = temp + ‘1‘;
32    }
33    printf("一付新牌的排列:\n");
34    ShowCard();    //显示新牌的排列
35    Shuffle();    //洗牌
36    printf("\n洗牌后的排列:\n");
37    ShowCard();    //显示新牌的排列
38    getch();
39    return 0;
40 }
41 void ShowCard() //显示牌
42 {
43    int i, j;
44    for (i = 0, j = 0; i < 52; i++, j++)
45    {
46       if (!(j % 13))
47          printf("\n");
48       printf("  %c%c", card1[i].Suit, card1[i].Number);
49    }
50    printf("\n");
51 }
52 void Shuffle() //洗牌
53 {
54    int i, j;
55    Card tempcard;
56    srand((int) time(0));
57    for (i = 0; i < 52; i++)
58    {
59       j = rand() % 52;    //随机换牌，将牌的顺序打乱,达到洗牌的效果
60       tempcard = card1[j];
61       card1[j] = card1[i];
62       card1[i] = tempcard;
63    }
64 }```

8-27 b&wchess.c

```  1 #include <stdio.h>
2 void Output(char chessboard[][8]);    //显示棋盘中下子的情况
3 int Check(char chessboard[][8], int moves[][8], char player);    //检查一方是否有地方可下子
4 void PlayStep(char chessboard[][8], int row, int col, char player);    //在指定位置下子
5 void AutoPlayStep(char chessboard[][8], int moves[][8], char player);    //计算机在思考下子
6 int GetMaxScore(char chessboard[][8], char player);    //获取分数
7 int BestPlay(char chessboard[][8], int moves[][8], char player);    //最优下子
8 int main()
9 {
10    char chessboard[8][8];    //保存棋盘中各单元格下子的状态
11    int isDown[8][8] = { 0 };    //保存棋盘中各位置是否可以下子，可下子的位置为1，其余位置为0
12    int row, col, x, y;
13    int iCount = 0;    //已下棋子数量
14    int player = 0;    //下棋方
15    int SkipPlay = 0;    //跳过下子的次数，若为2，表示双方都不能下子
16    int Score[2];    //保存计算机和游戏者的得分
17    char select;
18    printf("黑白棋\n\n");
19    printf("游戏者执黑先下，计算机执白，按Enter开始:\n");
20    scanf("%c", &select);
21    do
22    {
23       if (player == 0)    //计算下棋方(0表示游戏者,1表示计算机)
24          player = 1;
25       else
26          player = 0;
27       iCount = 4;    //累计下子数
28       for (row = 0; row < 8; row++)    //棋盘各位置清空
29          for (col = 0; col < 8; col++)
30             chessboard[row][col] = 0;
31       chessboard[3][3] = chessboard[4][4] = 1;    //在棋盘中间位置放置白棋
32       chessboard[3][4] = chessboard[4][3] = -1;    //在棋盘中间位置放置黑棋
33       printf("\n棋盘初始状态:\n");
34       Output(chessboard);    //显示初始棋盘下子的状况
35       do
36       {
37          if (player == 1)    //若是游戏者下棋(下白子)
38          {
39             player = 0;
40             if (Check(chessboard, isDown, 2))    //判断是否可下黑子
41             {
42                while(1)    //死循环，直到用户输入正确的坐标为止
43                {
44                   fflush(stdin);
45                   printf("输入下子的位置(行 列):");
46                   scanf("%d%c", &x, &y);
47                   x--;    //计算行坐标位置
48                   if(y >= ‘a‘)
49                       y = y - ‘a‘ + 1;
50                   else
51                       y = y - ‘A‘ + 1;
52                   y--;    //计算列位置
53                   if (x >= 0 && y >= 0 && x < 8 && y < 8 && isDown[x][y])    //若行列坐标输入有效
54                   {
55                      PlayStep(chessboard, x, y, 2);    //在指定坐标位置下黑子
56                      iCount++;    //累加下子数
57                      break;
58                   }
59                   else
60                      printf("坐标输入错误，请重新输入。\n");
61                }
62                printf("\n你下子后的状态:\n");
63                Output(chessboard);    //显示棋子状态
64                printf("按任意键计算机下子。\n");
65                getch();
66             }
67             else if (++SkipPlay < 2)    //若无效下子的次数小于2
68             {
69                fflush(stdin);    //清除输入缓冲区
70                printf("你没位置可下，按Enter键让对方下子。");
71                scanf("%c", &select);
72             } else
73                printf("双方都没地方下子，游戏结束!\n");
74          }
75          else    //若是计算机下棋(下黑子)
76          {
77             player = 1;
78             if (Check(chessboard, isDown, 1))    //检查是否可下白子
79             {
80                SkipPlay = 0;    //清除无效下子次数
81                AutoPlayStep(chessboard, isDown, 1);    //计算机下一个白子
82                iCount++;    //累加下子数
83                printf("\n计算机下子后的状态:\n");
84                Output(chessboard);    //显示棋子状态
85             }
86             else
87             {
88                if (++SkipPlay < 2)    //若无效下子次数小于2
89                   printf("我没位置可走，请你走。\n");
90                else
91                   printf("双方都没地方下子，游戏结束!");
92             }
93          }
94       }while (iCount < 64 && SkipPlay < 2);    //下子数量小于64 且无效下子的次数小于2
95       Output(chessboard);    //显示各双方棋子的状况
96       Score[0] = Score[1] = 0;    //清空计分变量
97       for (row = 0; row < 8; row++)    //循环统计各单元格黑白棋子的数量
98       {
99          for (col = 0; col < 8; col++)
100          {
101             Score[0] += chessboard[row][col] == -1;    //统计黑子数
102             Score[1] += chessboard[row][col] == 1;    //统计白子数
103          }
104       }
105       printf("最终成绩:\n");
106       printf("计算机:%d\n游戏者:%d\n", Score[0], Score[1]);
107       fflush(stdin);    //清空输入缓冲区
108       printf("继续下一局(y/n)？:");
109       scanf("%c", &select);
110    }while (select == ‘y‘ || select == ‘Y‘);
111    printf("Game Over!\n");
112    getch();
113    return 0;
114 }
115 void Output(char chessboard[][8])    //显示棋盘上棋子的状态
116 {
117    int row, col;
118    printf("\n   ");
119    for (col = 0; col < 8; col++)    //输出列标号
120       printf("  %c ", ‘A‘ + col);
121    printf("\n");
122    printf("  ┌");    //输出项部横线
123    for (col = 0; col < 7; col++)    //输出一行
124       printf("─┬");
125    printf("─┐\n");
126    for (row = 0; row < 8; row++)
127    {
128       printf("%2d│", row + 1);    //输出行号
129       for (col = 0; col < 8; col++)    //输出棋盘各单元格中棋子的状态
130       {
131          if (chessboard[row][col] == 1)    //白棋
132             printf("○│");
133          else if (chessboard[row][col] == -1)    //黑棋
134             printf("●│");
135          else    //未下子处
136             printf("  │");
137       }
138       printf("\n");
139       if (row < 8 - 1)
140       {
141          printf("  ├");    //输出交叉线
142          for (col = 0; col < 8 - 1; col++)    //输出一行
143             printf("─┼");
144          printf("─┤\n");
145       }
146    }
147    printf("  └");
148    for (col = 0; col < 8 - 1; col++)    //最后一行的横线
149       printf("─┴");
150    printf("─┘\n");
151 }
152 int Check(char chessboard[][8], int isDown[][8], char player)    //检查某一方是否还有下子的地方
153 {
154    int rowdelta, coldelta, row, col, x, y = 0;
155    int iStep = 0;
156    char opponent = (player == 1) ? -1 : 1;    //对方棋子
157    char myplayer = -1 * opponent;    //我方棋子
158    for (row = 0; row < 8; row++)    //将isDown数组全部清0
159       for (col = 0; col < 8; col++)
160          isDown[row][col] = 0;
161    for (row = 0; row < 8; row++)    //循环判断棋盘中哪些单元格可以下子
162    {
163       for (col = 0; col < 8; col++)
164       {
165          if (chessboard[row][col] != 0)    //若棋盘上对应位置不为空(表示已经有子)
166             continue;    //继续处理下一个单元格
167          for (rowdelta = -1; rowdelta <= 1; rowdelta++)    //循环检查上下行
168          {
169             for (coldelta = -1; coldelta <= 1; coldelta++)    //循环检查左右列
170             {
171                if (row + rowdelta < 0 || row + rowdelta >= 8
172                   || col + coldelta < 0 || col + coldelta >= 8
173                   || (rowdelta == 0 && coldelta == 0))    //检查若坐标超过棋盘 或为当前单元格
174                   continue;    //继续循环
175                if (chessboard[row + rowdelta][col + coldelta] == opponent)    //若(row,col)四周有对手下的子
176                {
177                   x = row + rowdelta;    //以对手下子位置为坐标
178                   y = col + coldelta;
179
180                   while(1)    //对对手下子为起始点，向四周查找自己方的棋子，以攻击对方棋子
181                   {
182                      x += rowdelta;    //对手下子的四周坐标
183                      y += coldelta;
184
185                      if (x < 0 || x >= 8 || y < 0 || y >= 8)    //超过棋盘
186                         break;    //退出循环
187
188                      if (chessboard[x][y] == 0)    //若对应位置为空
189                         break;
190                      if (chessboard[x][y] == myplayer)    //若对应位置下的子是当前棋手的
191                      {
192                         isDown[row][col] = 1;    //设置移动数组中对应位置为1 (该位置可下子，形成向对手进攻的棋形)
193                         iStep++;    //累加可下子的位置数量
194                         break;
195                      }
196                   }
197                }
198             }
199          }
200       }
201    }
202    return iStep;    //返回可下的位置数量（若返回值为0，表示没地方可下）
203 }
204 void PlayStep(char chessboard[][8], int row, int col, char player)    //在指定位置下子
205 {
206    int rowdelta = 0;
207    int coldelta = 0;
208    int x = 0;
209    int y = 0;
210    char opponent = (player == 1) ? -1 : 1;    //对方棋子
211    char myplayer = -1 * opponent;    //我方棋子
212    chessboard[row][col] = myplayer;    //保存所下的棋子
213    for (rowdelta = -1; rowdelta <= 1; rowdelta++)    //检查所下子四周的棋子
214    {
215       for (coldelta = -1; coldelta <= 1; coldelta++)
216       {
217          if (row + rowdelta < 0 || row + rowdelta >= 8 || col + coldelta < 0
218             || col + coldelta >= 8 || (rowdelta == 0 && coldelta == 0))    //若坐标超过棋盘界限
219             continue;    //继续下一位置
220          if (chessboard[row + rowdelta][col + coldelta] == opponent)    //若该位置是对手的棋子
221          {
222             x = row + rowdelta;    //以对手棋为坐标
223             y = col + coldelta;
224             while(1)    //在对手棋子四周寻找我方棋子
225             {
226                x += rowdelta;
227                y += coldelta;
228                if (x < 0 || x >= 8 || y < 0 || y >= 8)    //若坐标超过棋盘
229                   break;    //退出循环
230                if (chessboard[x][y] == 0)    //若对应位置为空
231                   break;    //退出循环
232                if (chessboard[x][y] == myplayer)    //若对应位置是我方模子
233                {
234                   while (chessboard[x -= rowdelta][y -= coldelta] == opponent)    //循环处理
235                      chessboard[x][y] = myplayer;    //将中间的棋子都变成我方棋子
236                   break;    //退出循环
237                }
238             }
239          }
240       }
241    }
242 }
243 int GetMaxScore(char chessboard[][8], char player)    //获取分数
244 {
245    int Score, row, col;
246    char opponent = (player == 1) ? -1 : 1;    //对方棋子
247    char myplayer=-1*opponent;
248    for (row = 0; row < 8; row++)    //循环
249    {
250       for (col = 0; col < 8; col++)
251       {
252          Score -= chessboard[row][col] == opponent;    //若棋盘对应位置是对手下的棋子，从总分中减1
253          Score += chessboard[row][col] == myplayer;    //若棋盘对应位置是我方的棋子，总分中加1分
254       }
255    }
256    return Score;    //返回分数
257 }
258 int BestPlay(char chessboard[][8], int isDown[][8], char player)    //获取最佳下子位置
259 {
260    int row, col, i, j;
261    char chessboard1[8][8] = { 0 };    //定义一个临时数组
262    int MaxScore = 0;    //保存最高分
263    int Score = 0;
264    char opponent = (player == 1) ? -1 : 1;    //对手下的棋子
265    for (row = 0; row < 8; row++)    //循环检查每个单元格
266    {
267       for (col = 0; col < 8; col++)
268       {
269          if (!isDown[row][col])    //若该位置不可下子
270             continue;    //继续
271          for (i = 0; i < 8; i++)    //复制棋盘各单元格下子的状态到临时数组
272             for (j = 0; j < 8; j++)
273                chessboard1[i][j] = chessboard[i][j];
274          PlayStep(chessboard1, row, col, player);    //在临时数组中的指定行列下子
275          Score = GetMaxScore(chessboard1, player);    //获取下子后可得到的分数
276          if (MaxScore < Score)    //若原方案得到的分数小于本次下子的分数
277             MaxScore = Score;    //保存最高分
278       }
279    }
280    return MaxScore;    //返回得到的最高分
281 }
282 void AutoPlayStep(char chessboard[][8], int isDown[][8], char player)    //计算机自动下子
283 {
284    int row, col, row1, col1, i, j;
285    int Score = 0, MinScore = 100;    //对方可下子提到的分数和最小分数
286    char chessboard1[8][8];    //临时数组，保存棋盘下子位置
287    int isDown1[8][8];    //临时数组，保存可下子位置
288    char opponent = (player == 1) ? -1 : 1;    //对手下的棋子
289    for (row = 0; row < 8; row++)    //循环检查棋盘每个单元格
290    {
291       for (col = 0; col < 8; col++)
292       {
293          if (isDown[row][col] == 0)    //若不可下子
294             continue;    //继续下一个位置
295          for (i = 0; i < 8; i++)    //将棋盘原来的棋子复制到临时数组中
296             for (j = 0; j < 8; j++)
297                chessboard1[i][j] = chessboard[i][j];
298          PlayStep(chessboard1, row, col, player);    //试着在临时棋盘中的一个位子下子
299          Check(chessboard1, isDown1, opponent);    //检查对手是否有地方可下子
300          Score = BestPlay(chessboard1, isDown1, opponent);    //获得临时棋盘中对方下子的得分情况
301          if (Score < MinScore)    //保存对方得分最低的下法
302          {
303             MinScore = Score;
304             row1 = row;
305             col1 = col;
306          }
307       }
308    }
309    PlayStep(chessboard, row1, col1, player);    //计算机按最优下法下子
310 }```

#include <stdio.h>void Output(char chessboard[][8]); //显示棋盘中下子的情况 int Check(char chessboard[][8], int moves[][8], char player); //检查一方是否有地方可下子 void PlayStep(char chessboard[][8], int row, int col, char player); //在指定位置下子 void AutoPlayStep(char chessboard[][8], int moves[][8], char player); //计算机在思考下子 int GetMaxScore(char chessboard[][8], char player); //获取分数 int BestPlay(char chessboard[][8], int moves[][8], char player); //最优下子 int main()
{
char chessboard[8][8]; //保存棋盘中各单元格下子的状态 int isDown[8][8] = { 0 }; //保存棋盘中各位置是否可以下子，可下子的位置为1，其余位置为0 int row, col, x, y;
int iCount = 0; //已下棋子数量 int player = 0; //下棋方int SkipPlay = 0; //跳过下子的次数，若为2，表示双方都不能下子 int Score[2]; //保存计算机和游戏者的得分 char select;
printf("黑白棋\n\n");
printf("游戏者执黑先下，计算机执白，按Enter开始:\n");
scanf("%c", &select);
do
{
if (player == 0) //计算下棋方(0表示游戏者,1表示计算机)
player = 1;
else
player = 0;
iCount = 4; //累计下子数 for (row = 0; row < 8; row++) //棋盘各位置清空 for (col = 0; col < 8; col++)
chessboard[row][col] = 0;
chessboard[3][3] = chessboard[4][4] = 1; //在棋盘中间位置放置白棋
chessboard[3][4] = chessboard[4][3] = -1; //在棋盘中间位置放置黑棋 printf("\n棋盘初始状态:\n");
Output(chessboard); //显示初始棋盘下子的状况 do
{
if (player == 1) //若是游戏者下棋(下白子)
{
player = 0;
if (Check(chessboard, isDown, 2)) //判断是否可下黑子
{
while(1) //死循环，直到用户输入正确的坐标为止
{
fflush(stdin);
printf("输入下子的位置(行 列):");
scanf("%d%c", &x, &y);
x--; //计算行坐标位置 if(y >= ‘a‘)
y = y - ‘a‘ + 1;
else
y = y - ‘A‘ + 1;
y--; //计算列位置 if (x >= 0 && y >= 0 && x < 8 && y < 8 && isDown[x][y]) //若行列坐标输入有效
{
PlayStep(chessboard, x, y, 2); //在指定坐标位置下黑子
iCount++; //累加下子数 break;
}
elseprintf("坐标输入错误，请重新输入。\n");
}
printf("\n你下子后的状态:\n");
Output(chessboard); //显示棋子状态printf("按任意键计算机下子。\n");
getch();
}
elseif (++SkipPlay < 2) //若无效下子的次数小于2
{
fflush(stdin); //清除输入缓冲区 printf("你没位置可下，按Enter键让对方下子。");
scanf("%c", &select);
} elseprintf("双方都没地方下子，游戏结束!\n");
}
else//若是计算机下棋(下黑子)
{
player = 1;
if (Check(chessboard, isDown, 1)) //检查是否可下白子
{
SkipPlay = 0; //清除无效下子次数
AutoPlayStep(chessboard, isDown, 1); //计算机下一个白子
iCount++; //累加下子数printf("\n计算机下子后的状态:\n");
Output(chessboard); //显示棋子状态
}
else
{
if (++SkipPlay < 2) //若无效下子次数小于2 printf("我没位置可走，请你走。\n");
elseprintf("双方都没地方下子，游戏结束!");
}
}
}while (iCount < 64 && SkipPlay < 2); //下子数量小于64 且无效下子的次数小于2
Output(chessboard); //显示各双方棋子的状况
Score[0] = Score[1] = 0; //清空计分变量 for (row = 0; row < 8; row++) //循环统计各单元格黑白棋子的数量
{
for (col = 0; col < 8; col++)
{
Score[0] += chessboard[row][col] == -1; //统计黑子数
Score[1] += chessboard[row][col] == 1; //统计白子数
}
}
printf("最终成绩:\n");
printf("计算机:%d\n游戏者:%d\n", Score[0], Score[1]);
fflush(stdin); //清空输入缓冲区 printf("继续下一局(y/n)？:");
scanf("%c", &select);
}while (select == ‘y‘ || select == ‘Y‘);
printf("Game Over!\n");
getch();
return0;
}
void Output(char chessboard[][8]) //显示棋盘上棋子的状态
{
int row, col;
printf("\n ");
for (col = 0; col < 8; col++) //输出列标号 printf(" %c ", ‘A‘ + col);
printf("\n");
printf(" ┌"); //输出项部横线 for (col = 0; col < 7; col++) //输出一行 printf("─┬");
printf("─┐\n");
for (row = 0; row < 8; row++)
{
printf("%2d│", row + 1); //输出行号for (col = 0; col < 8; col++) //输出棋盘各单元格中棋子的状态
{
if (chessboard[row][col] == 1) //白棋 printf("○│");
elseif (chessboard[row][col] == -1) //黑棋 printf("●│");
else//未下子处 printf(" │");
}
printf("\n");
if (row < 8 - 1)
{
printf(" ├"); //输出交叉线 for (col = 0; col < 8 - 1; col++) //输出一行 printf("─┼");
printf("─┤\n");
}
}
printf(" └");
for (col = 0; col < 8 - 1; col++) //最后一行的横线 printf("─┴");
printf("─┘\n");
}
int Check(char chessboard[][8], int isDown[][8], char player) //检查某一方是否还有下子的地方
{
int rowdelta, coldelta, row, col, x, y = 0;
int iStep = 0;
char opponent = (player == 1) ? -1 : 1; //对方棋子 char myplayer = -1 * opponent; //我方棋子 for (row = 0; row < 8; row++) //将isDown数组全部清0 for (col = 0; col < 8; col++)
isDown[row][col] = 0;
for (row = 0; row < 8; row++) //循环判断棋盘中哪些单元格可以下子
{
for (col = 0; col < 8; col++)
{
if (chessboard[row][col] != 0) //若棋盘上对应位置不为空(表示已经有子) continue; //继续处理下一个单元格 for (rowdelta = -1; rowdelta <= 1; rowdelta++) //循环检查上下行
{
for (coldelta = -1; coldelta <= 1; coldelta++) //循环检查左右列
{
if (row + rowdelta < 0 || row + rowdelta >= 8
|| col + coldelta < 0 || col + coldelta >= 8
|| (rowdelta == 0 && coldelta == 0)) //检查若坐标超过棋盘 或为当前单元格 continue; //继续循环 if (chessboard[row + rowdelta][col + coldelta] == opponent) //若(row,col)四周有对手下的子
{
x = row + rowdelta; //以对手下子位置为坐标
y = col + coldelta;

while(1) //对对手下子为起始点，向四周查找自己方的棋子，以攻击对方棋子
{
x += rowdelta; //对手下子的四周坐标
y += coldelta;

if (x < 0 || x >= 8 || y < 0 || y >= 8) //超过棋盘 break; //退出循环 if (chessboard[x][y] == 0) //若对应位置为空 break;
if (chessboard[x][y] == myplayer) //若对应位置下的子是当前棋手的
{
isDown[row][col] = 1; //设置移动数组中对应位置为1 (该位置可下子，形成向对手进攻的棋形)
iStep++; //累加可下子的位置数量 break;
}
}
}
}
}
}
}
return iStep; //返回可下的位置数量（若返回值为0，表示没地方可下）
}
void PlayStep(char chessboard[][8], int row, int col, char player) //在指定位置下子
{
int rowdelta = 0;
int coldelta = 0;
int x = 0;
int y = 0;
char opponent = (player == 1) ? -1 : 1; //对方棋子char myplayer = -1 * opponent; //我方棋子
chessboard[row][col] = myplayer; //保存所下的棋子for (rowdelta = -1; rowdelta <= 1; rowdelta++) //检查所下子四周的棋子
{
for (coldelta = -1; coldelta <= 1; coldelta++)
{
if (row + rowdelta < 0 || row + rowdelta >= 8 || col + coldelta < 0
|| col + coldelta >= 8 || (rowdelta == 0 && coldelta == 0)) //若坐标超过棋盘界限 continue; //继续下一位置 if (chessboard[row + rowdelta][col + coldelta] == opponent) //若该位置是对手的棋子
{
x = row + rowdelta; //以对手棋为坐标
y = col + coldelta;
while(1) //在对手棋子四周寻找我方棋子
{
x += rowdelta;
y += coldelta;
if (x < 0 || x >= 8 || y < 0 || y >= 8) //若坐标超过棋盘 break; //退出循环 if (chessboard[x][y] == 0) //若对应位置为空 break; //退出循环 if (chessboard[x][y] == myplayer) //若对应位置是我方模子
{
while (chessboard[x -= rowdelta][y -= coldelta] == opponent) //循环处理
chessboard[x][y] = myplayer; //将中间的棋子都变成我方棋子 break; //退出循环
}
}
}
}
}
}
int GetMaxScore(char chessboard[][8], char player) //获取分数
{
int Score, row, col;
char opponent = (player == 1) ? -1 : 1; //对方棋子 char myplayer=-1*opponent;
for (row = 0; row < 8; row++) //循环
{
for (col = 0; col < 8; col++)
{
Score -= chessboard[row][col] == opponent; //若棋盘对应位置是对手下的棋子，从总分中减1
Score += chessboard[row][col] == myplayer; //若棋盘对应位置是我方的棋子，总分中加1分
}
}
return Score; //返回分数
}
int BestPlay(char chessboard[][8], int isDown[][8], char player) //获取最佳下子位置
{
int row, col, i, j;
char chessboard1[8][8] = { 0 }; //定义一个临时数组 int MaxScore = 0; //保存最高分 int Score = 0;
char opponent = (player == 1) ? -1 : 1; //对手下的棋子 for (row = 0; row < 8; row++) //循环检查每个单元格
{
for (col = 0; col < 8; col++)
{
if (!isDown[row][col]) //若该位置不可下子 continue; //继续 for (i = 0; i < 8; i++) //复制棋盘各单元格下子的状态到临时数组 for (j = 0; j < 8; j++)
chessboard1[i][j] = chessboard[i][j];
PlayStep(chessboard1, row, col, player); //在临时数组中的指定行列下子
Score = GetMaxScore(chessboard1, player); //获取下子后可得到的分数if (MaxScore < Score) //若原方案得到的分数小于本次下子的分数
MaxScore = Score; //保存最高分
}
}
return MaxScore; //返回得到的最高分
}
void AutoPlayStep(char chessboard[][8], int isDown[][8], char player) //计算机自动下子
{
int row, col, row1, col1, i, j;
int Score = 0, MinScore = 100; //对方可下子提到的分数和最小分数 char chessboard1[8][8]; //临时数组，保存棋盘下子位置 int isDown1[8][8]; //临时数组，保存可下子位置 char opponent = (player == 1) ? -1 : 1; //对手下的棋子 for (row = 0; row < 8; row++) //循环检查棋盘每个单元格
{
for (col = 0; col < 8; col++)
{
if (isDown[row][col] == 0) //若不可下子 continue; //继续下一个位置 for (i = 0; i < 8; i++) //将棋盘原来的棋子复制到临时数组中 for (j = 0; j < 8; j++)
chessboard1[i][j] = chessboard[i][j];
PlayStep(chessboard1, row, col, player); //试着在临时棋盘中的一个位子下子
Check(chessboard1, isDown1, opponent); //检查对手是否有地方可下子
Score = BestPlay(chessboard1, isDown1, opponent); //获得临时棋盘中对方下子的得分情况 if (Score < MinScore) //保存对方得分最低的下法
{
MinScore = Score;
row1 = row;
col1 = col;
}
}
}
PlayStep(chessboard, row1, col1, player); //计算机按最优下法下子
}

## 8.5 趣味游戏(1)

8-24 stone.c 1 #include <stdio.h> 2 unsigned int *heap; //保存各堆石子的数量 3 int num; 4 void Output() //显示各堆石子的状态 5 { 6 int i; 7 printf("各堆剩下的石子数量:\n"); 8 for (i = 1; i <= num; i++) 9 printf("第%2d堆剩下: %u \n", i, heap[i]); 10 } 11 uns