用C语言实现井字棋(人人/AI人机)--完结版
若本文章为原创文章,转载本文时需加上本文原地址
用C语言实现井字棋(人人/AI人机)--完结版
刚好凑够一个月才动身
完结版将之前见到的BUG消灭啦,开心!
现在暂时试不出BUG
源码放在下面,试错视频链接也放在下面
完结版试错(B站)==>地址
旧版源码和思路在CSDN==>地址
因为改的地方只有电脑下棋的逻辑,其他的旧版的文章都有,我就不赘述了
BUG与优化3:
1. 修改了step的计算方法,每个玩家玩完就加一次step
2. 改变了电脑下棋的逻辑,每个玩家玩完之后都跳过这次循环
void play_computer()
{
play_mode = 1; //人机对战模式
player = 1; //玩家先出手 (1为玩家,-1为电脑)
int temp = 1; //1为◆状态,-1为★状态
int x, y; //行、列坐标
menu();
draw();
COM_play_mode:
gotoxy(26, 22);
printf_s("你想设置电脑的下棋模式为防守/进攻为主?(0-1): "); //清空
gotoxy(26, 22);
printf_s("你想设置电脑的下棋模式为防守/进攻为主?(0-1):");
scanf_s("%d", &offence_defence);
if (leagality_check(offence_defence, 0, 1) == 0) goto COM_play_mode;
gotoxy(55, 12);
if (offence_defence == 0) printf_s("当前电脑下棋模式:防守");
else printf_s("当前电脑下棋模式:进攻");
while (1)
{
if (win_check() != 0) break;
if (step < 9)
{
gotoxy(20, 22);
printf_s(" ");
/*-------------------打印当前棋子信息-----------------------*/
gotoxy(54, 9);
printf_s("╔ ═ ╗");
gotoxy(54, 11);
printf_s("╚ ═ ╝");
gotoxy(55, 10);
if (temp == 1) printf_s("当前棋子:◆");
if (temp == -1) printf_s("当前棋子:★");
/*----------------------------------------------------------*/
com_play:
/*先清空原先输入的坐标*/
gotoxy(54, 17);
printf_s("请输入行坐标(1-3): ");
gotoxy(54, 18);
printf_s("请输入列坐标(1-3): ");
gotoxy(26, 22);
printf_s(" ");
/*----------------------------------------------------------*/
if (player == 1)
{
gotoxy(54, 17);
printf_s("请输入行坐标(1-3):");
scanf_s("%d", &x);
if (leagality_check(x, 1, 3) == 0) goto com_play;
gotoxy(54, 18);
printf_s("请输入列坐标(1-3):");
scanf_s("%d", &y);
if (leagality_check(y, 1, 3) == 0) goto com_play;
if (board[x - 1][y - 1] == 0)
{
board[x - 1][y - 1] = temp;
update();
temp *= -1;
}
else
{
gotoxy(26, 22);
printf_s("该坐标已有棋,请重下!");
getchar();
getchar(); //让玩家看得到信息
goto com_play;
}
++step;
player *= -1; //玩家先出手 (1为玩家,-1为电脑)
continue;
}
if (player == -1)
{
switch (weight_and_choose())
{
case 1: if (board[0][0] == 0) board[0][0] = -1; break;
case 2: if (board[0][1] == 0) board[0][1] = -1; break;
case 3: if (board[0][2] == 0) board[0][2] = -1; break;
case 4: if (board[1][0] == 0) board[1][0] = -1; break;
case 5: if (board[1][1] == 0) board[1][1] = -1; break;
case 6: if (board[1][2] == 0) board[1][2] = -1; break;
case 7: if (board[2][0] == 0) board[2][0] = -1; break;
case 8: if (board[2][1] == 0) board[2][1] = -1; break;
case 9: if (board[2][2] == 0) board[2][2] = -1; break;
}
/*------------单纯为了好玩,让玩家不会觉得自己孤独-------------*/
gotoxy(23, 22);
printf_s("电脑正在思考,请输入任意键以继续");
getchar();
getchar();
update();
temp *= -1;
player *= -1;
++step;
continue;
}
}
}
switch (win_check())
{
case 1: MessageBox(NULL, TEXT("你真棒,你获得胜利!"), TEXT("输赢判断"), MB_OK); break;
case 2: MessageBox(NULL, TEXT("电脑真棒,电脑获得胜利!"), TEXT("输赢判断"), MB_OK); break;
case 3: MessageBox(NULL, TEXT("平局!!!"), TEXT("输赢判断"), MB_OK); break;
}
}
其实看起来还是没什么差别,但是逻辑改变之后调试变得很快乐,(●'◡'●)
源码:
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h> //随机数用
/*
project name: 井字棋(Tic-Tac-Toe)
author name: dragonet
date: 2020/7/15——2020/8/15(版本3)
*/
/*
BUG与优化1:
1. 更名weight_calculating为weight_and_choose,并将原先的权重计算与选择函数合并
2. 取消原先的权重计算方法,(效率过低),现改为直接堵门或者直接三连,如果都不行就直接随机数
3. 增加times全局变量记录同行、列、对角线上同种棋的个数,将原先两种棋在一起判断改为分开判断,增加效率
4. 选择下棋逻辑,根据玩家输入的电脑下棋模式,优先选择堵门或者三连O(∩_∩)O
BUG与优化2:
1. 修改了step的计算方法
2. 改变了电脑下棋的逻辑
*/
/*全局变量区*/
int board[3][3] = {0}; //0代表空,1代表◆,-1代表★
int player; //1代表玩家、-1代表电脑
int play_mode = 0; //0代表自娱自乐,1代表人机对战
int step = 0; //走的步数
int offence_defence; //电脑的下棋模式选择为进攻还是防守,0为防守,1为进攻
int times = 0;
/*函数声明区*/
void gotoxy(int x, int y); //改变下个语句的输入、输出位置
void menu(); //讲解规则,开始界面
void draw(); //打印棋盘面板
void update(); //更新棋盘
int leagality_check(int t, int minnum, int maxnum); //输入合法性检查,主要判断数字是否在范围内
void play_own(); //自娱自乐玩法
void play_computer(); //人机对战玩法
int weight_and_choose(); //权重计算
int win_check(); //输赢判断,0为无法判断,1为◆赢,2为★赢,3为平局
int main()
{
system("mode con cols=90 lines=30");
int n = 0;
Mode_choice:
printf_s("请输入想要玩的模式(1代表自娱自乐,2代表人机对战):");
scanf_s("%d", &n);
if (leagality_check(n, 1, 2) == 0) goto Mode_choice;
gotoxy(0, 0);
if (n == 2)
{
for (n = 0; n < 200; ++n)
printf_s(" \n"); //清空所有
play_computer();
}
else
{
for (n = 0; n < 200; ++n)
printf_s(" \n"); //清空所有
play_own();
}
gotoxy(23, 22);
system("pause");
return 0;
}
void menu()
{
gotoxy(23, 2);
printf_s("欢迎来玩井字游戏(Tic-Tac-Toe)!");
gotoxy(30, 3);
printf_s("下面开始介绍规则");
gotoxy(10, 4);
printf_s("1. 赢局:任意行、列、对角线先占满三个同种棋,则该种棋的玩家赢");
gotoxy(10, 5);
printf_s("2. 输局:只存在于人机对战,任意行、列、对角线被电脑先占满三个棋");
gotoxy(10, 6);
printf_s("3. 平局:全部格子都已被占满且未分出胜负");
gotoxy(10, 7);
printf_s("4. 默认都是玩家先出手,且棋类型为◆");
}
void draw()
{
gotoxy(26, 8);
printf_s("┏━━━━━━━┳━━━━━━━┳━━━━━━━┓");
gotoxy(26, 9);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 10);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 11);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 12);
printf_s("┣━━━━━━━╋━━━━━━━╋━━━━━━━┫");
gotoxy(26, 13);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 14);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 15);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 16);
printf_s("┣━━━━━━━╋━━━━━━━╋━━━━━━━┫");
gotoxy(26, 17);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 18);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 19);
printf_s("┃ ┃ ┃ ┃");
gotoxy(26, 20);
printf_s("┗━━━━━━━┻━━━━━━━┻━━━━━━━┛");
gotoxy(26, 21);
printf_s("注:输错的话要重输的喔");
}
void gotoxy(int x, int y) {
COORD pos = { x,y };
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
void update()
{
int xp, yp;
for (int i = 0; i < 3; ++i)
{
yp = 10 + (i * 4);
for (int j = 0; j < 3; ++j)
{
xp = 30 + (j * 8);
gotoxy(xp, yp);
if (board[i][j] == 0) printf_s(" ");
if (board[i][j] == 1) printf_s("◆");
if (board[i][j] == -1) printf_s("★");
printf_s("\t");
}
printf_s("\n");
}
}
int leagality_check(int t, int minnum, int maxnum)
{
for (int i = minnum; i <= maxnum; ++i) if (t == i) return 1;
return 0;
}
void play_own()
{
player = 1; //从头到尾都是玩家
play_mode = 0; //自娱自乐模式
int temp = 1; //1为◆状态,-1为★状态
int x, y; //行、列坐标
menu(); //介绍面板
draw(); //初始化棋盘面板
while (win_check() == 0)
{
++step; //步数增加
/*-----------------打印当前棋子信息-----------------------*/
gotoxy(54, 9);
printf_s("╔ ═ ╗");
gotoxy(54, 11);
printf_s("╚ ═ ╝");
gotoxy(55, 10);
if (temp == 1) printf_s("当前棋子:◆");
if (temp == -1) printf_s("当前棋子:★");
/*----------------------------------------------------------*/
own_play:
/*先清空原先输入的坐标*/
gotoxy(54, 17);
printf_s("请输入行坐标(1-3): ");
gotoxy(54, 18);
printf_s("请输入列坐标(1-3): ");
gotoxy(26, 22);
printf_s(" ");
/*----------------------------------------------------------*/
gotoxy(54, 17);
printf_s("请输入行坐标(1-3):");
scanf_s("%d", &x);
if (leagality_check(x, 1, 3) == 0) goto own_play;
gotoxy(54, 18);
printf_s("请输入列坐标(1-3):");
scanf_s("%d", &y);
if (leagality_check(y, 1, 3) == 0) goto own_play;
if (board[x - 1][y - 1] == 0)
{
board[x - 1][y - 1] = temp;
update();
temp *= -1;
}
else
{
gotoxy(26,22);
printf_s("该坐标已有棋,请重下!");
getchar();
getchar(); //让玩家看得到信息
goto own_play;
}
}
switch (win_check())
{
case 1: MessageBox(NULL, TEXT("恭喜◆方胜利"), TEXT("输赢判断"), MB_OK); break;
case 2: MessageBox(NULL, TEXT("恭喜★方胜利"), TEXT("输赢判断"), MB_OK); break;
case 3: MessageBox(NULL, TEXT("平局!!!"), TEXT("输赢判断"), MB_OK); break;
}
}
void play_computer()
{
play_mode = 1; //人机对战模式
player = 1; //玩家先出手 (1为玩家,-1为电脑)
int temp = 1; //1为◆状态,-1为★状态
int x, y; //行、列坐标
menu();
draw();
COM_play_mode:
gotoxy(26, 22);
printf_s("你想设置电脑的下棋模式为防守/进攻为主?(0-1): "); //清空
gotoxy(26, 22);
printf_s("你想设置电脑的下棋模式为防守/进攻为主?(0-1):");
scanf_s("%d", &offence_defence);
if (leagality_check(offence_defence, 0, 1) == 0) goto COM_play_mode;
gotoxy(55, 12);
if (offence_defence == 0) printf_s("当前电脑下棋模式:防守");
else printf_s("当前电脑下棋模式:进攻");
while (1)
{
if (win_check() != 0) break;
if (step < 9)
{
gotoxy(20, 22);
printf_s(" ");
/*-------------------打印当前棋子信息-----------------------*/
gotoxy(54, 9);
printf_s("╔ ═ ╗");
gotoxy(54, 11);
printf_s("╚ ═ ╝");
gotoxy(55, 10);
if (temp == 1) printf_s("当前棋子:◆");
if (temp == -1) printf_s("当前棋子:★");
/*----------------------------------------------------------*/
com_play:
/*先清空原先输入的坐标*/
gotoxy(54, 17);
printf_s("请输入行坐标(1-3): ");
gotoxy(54, 18);
printf_s("请输入列坐标(1-3): ");
gotoxy(26, 22);
printf_s(" ");
/*----------------------------------------------------------*/
if (player == 1)
{
gotoxy(54, 17);
printf_s("请输入行坐标(1-3):");
scanf_s("%d", &x);
if (leagality_check(x, 1, 3) == 0) goto com_play;
gotoxy(54, 18);
printf_s("请输入列坐标(1-3):");
scanf_s("%d", &y);
if (leagality_check(y, 1, 3) == 0) goto com_play;
if (board[x - 1][y - 1] == 0)
{
board[x - 1][y - 1] = temp;
update();
temp *= -1;
}
else
{
gotoxy(26, 22);
printf_s("该坐标已有棋,请重下!");
getchar();
getchar(); //让玩家看得到信息
goto com_play;
}
++step;
player *= -1; //玩家先出手 (1为玩家,-1为电脑)
continue;
}
if (player == -1)
{
switch (weight_and_choose())
{
case 1: if (board[0][0] == 0) board[0][0] = -1; break;
case 2: if (board[0][1] == 0) board[0][1] = -1; break;
case 3: if (board[0][2] == 0) board[0][2] = -1; break;
case 4: if (board[1][0] == 0) board[1][0] = -1; break;
case 5: if (board[1][1] == 0) board[1][1] = -1; break;
case 6: if (board[1][2] == 0) board[1][2] = -1; break;
case 7: if (board[2][0] == 0) board[2][0] = -1; break;
case 8: if (board[2][1] == 0) board[2][1] = -1; break;
case 9: if (board[2][2] == 0) board[2][2] = -1; break;
}
/*------------单纯为了好玩,让玩家不会觉得自己孤独-------------*/
gotoxy(23, 22);
printf_s("电脑正在思考,请输入任意键以继续");
getchar();
getchar();
update();
temp *= -1;
player *= -1;
++step;
continue;
}
}
}
switch (win_check())
{
case 1: MessageBox(NULL, TEXT("你真棒,你获得胜利!"), TEXT("输赢判断"), MB_OK); break;
case 2: MessageBox(NULL, TEXT("电脑真棒,电脑获得胜利!"), TEXT("输赢判断"), MB_OK); break;
case 3: MessageBox(NULL, TEXT("平局!!!"), TEXT("输赢判断"), MB_OK); break;
}
}
int weight_and_choose()
{
int n, i, j, k, randnum;
if (offence_defence == 0) //优先堵门
{
//对◆棋的判断(堵门!)
for (i = 0; i < 3; ++i)
for (j = 0; j < 3; ++j)
{
if (board[i][0] == 1 || board[i][1] == 1 || board[i][2] == 1) //行判断
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[i][n] == 1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[i][k] == 0) return 3 * i + k + 1;
}
}
}
if (board[0][i] == 1 || board[1][i] == 1 || board[2][i] == 1) //列判断
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[n][i] == 1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][i] == 0) return 3 * k + i + 1;
}
}
}
if (i == 0 && j == 0 || i == 0 && j == 2 || i == 1 && j == 1 || i == 2 && j == 0 || i == 2 && j == 2) //对角线判断
{
if (board[0][0] == 1 || board[1][1] == 1 || board[2][2] == 1) //正对角线
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[n][n] == 1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][k] == 0) return 3 * k + k + 1;
}
}
}
if (board[0][2] == 1 || board[1][1] == 1 || board[2][0] == 1) //副对角线
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[0 + n][2 - n] == 1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][2 - k] == 0) return 3 * (k + 1) - k;
}
}
}
}
}
//对★的判断(三连)
for (i = 0; i < 3; ++i)
for (j = 0; j < 3; ++j)
{
if (board[i][0] == -1 || board[i][1] == -1 || board[i][2] == -1) //行判断
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[i][n] == -1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[i][k] == 0) return 3 * i + k + 1;
}
}
}
if (board[0][i] == -1 || board[1][i] == -1 || board[2][i] == -1) //列判断
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[n][i] == -1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][i] == 0) return 3 * k + i + 1;
}
}
}
if (i == 0 && j == 0 || i == 0 && j == 2 || i == 1 && j == 1 || i == 2 && j == 0 || i == 2 && j == 2) //对角线判断
{
if (board[0][0] == -1 || board[1][1] == -1 || board[2][2] == -1) //正对角线
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[n][n] == -1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][k] == 0) return 3 * k + k + 1;
}
}
}
if (board[0][2] == -1 || board[1][1] == -1 || board[2][0] == -1) //副对角线
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[0 + n][2 - n] == -1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][2 - k] == 0) return 3 * (k + 1) - k;
}
}
}
}
}
}
if (offence_defence == 1) //优先三连
{
//对★的判断(三连)
for (i = 0; i < 3; ++i)
for (j = 0; j < 3; ++j)
{
if (board[i][0] == -1 || board[i][1] == -1 || board[i][2] == -1) //行判断
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[i][n] == -1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[i][k] == 0) return 3 * i + k + 1;
}
}
}
if (board[0][i] == -1 || board[1][i] == -1 || board[2][i] == -1) //列判断
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[n][i] == -1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][i] == 0) return 3 * k + i + 1;
}
}
}
if (i == 0 && j == 0 || i == 0 && j == 2 || i == 1 && j == 1 || i == 2 && j == 0 || i == 2 && j == 2) //对角线判断
{
if (board[0][0] == -1 || board[1][1] == -1 || board[2][2] == -1) //正对角线
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[n][n] == -1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][k] == 0) return 3 * k + k + 1;
}
}
}
if (board[0][2] == -1 || board[1][1] == -1 || board[2][0] == -1) //副对角线
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[0 + n][2 - n] == -1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][2 - k] == 0) return 3 * (k + 1) - k;
}
}
}
}
}
//对◆棋的判断(堵门!)
for (i = 0; i < 3; ++i)
for (j = 0; j < 3; ++j)
{
if (board[i][0] == 1 || board[i][1] == 1 || board[i][2] == 1) //行判断
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[i][n] == 1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[i][k] == 0) return 3 * i + k + 1;
}
}
}
if (board[0][i] == 1 || board[1][i] == 1 || board[2][i] == 1) //列判断
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[n][i] == 1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][i] == 0) return 3 * k + i + 1;
}
}
}
if (i == 0 && j == 0 || i == 0 && j == 2 || i == 1 && j == 1 || i == 2 && j == 0 || i == 2 && j == 2) //对角线判断
{
if (board[0][0] == 1 || board[1][1] == 1 || board[2][2] == 1) //正对角线
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[n][n] == 1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][k] == 0) return 3 * k + k + 1;
}
}
}
if (board[0][2] == 1 || board[1][1] == 1 || board[2][0] == 1) //副对角线
{
times = 0;
for (n = 0; n < 3; ++n)
{
if (board[0 + n][2 - n] == 1)
{
++times;
if (times == 2)
for (k = 0; k < 3; ++k)
if (board[k][2 - k] == 0) return 3 * (k + 1) - k;
}
}
}
}
}
}
//如果前两个没有能成功下棋,那就直接随机数下棋,不整花里胡哨的了
Suiji:
if (1)
{
time_t t;
srand((unsigned)time(&t));
randnum = rand() % 10 + 1; //1-9随机数
switch (randnum)
{
case 1:if (board[0][0] == 0) return randnum; else goto Suiji; break;
case 2:if (board[0][1] == 0) return randnum; else goto Suiji; break;
case 3:if (board[0][2] == 0) return randnum; else goto Suiji; break;
case 4:if (board[1][0] == 0) return randnum; else goto Suiji; break;
case 5:if (board[1][1] == 0) return randnum; else goto Suiji; break;
case 6:if (board[1][2] == 0) return randnum; else goto Suiji; break;
case 7:if (board[2][0] == 0) return randnum; else goto Suiji; break;
case 8:if (board[2][1] == 0) return randnum; else goto Suiji; break;
case 9:if (board[2][2] == 0) return randnum; else goto Suiji; break;
}
}
}
int win_check()
{
if (play_mode == 0) //自娱自乐模式下的判断
{
int i;
/*赢局的情况(◆与★)*/
for (i = 0; i < 3; ++i) //行
if (board[i][0] == 1 && board[i][1] == 1 && board[i][2] == 1 || board[i][0] == -1 && board[i][1] == -1 && board[i][2] == -1) break; //穷举行
if(board[i][0] == 1 && board[i][1] == 1 && board[i][2] == 1) return 1;
if(board[i][0] == -1 && board[i][1] == -1 && board[i][2] == -1) return 2;
/*-----------------------------*/
for (i = 0; i < 3; ++i) //列
if (board[0][i] == 1 && board[1][i] == 1 && board[2][i] == 1 || board[0][i] == -1 && board[1][i] == -1 && board[2][i] == -1) break; //穷举列
if (board[0][i] == 1 && board[1][i] == 1 && board[2][i] == 1) return 1;
if (board[0][i] == -1 && board[1][i] == -1 && board[2][i] == -1) return 2;
/*-----------------------------*/
//if (board[0][0]==board[1][1]==board[2][2] && board[0][0]!=0 && board[1][1]!=0 && board[2][2]!=0 || board[0][2]==board[1][1]==board[2][0] && board[0][2] != 0 && board[1][1] != 0 && board[2][0] != 0) //对角线
if (board[0][0] == 1 && board[1][1] == 1 && board[2][2] == 1 || board[0][2] == 1 && board[1][1] == 1 && board[2][0] == 1 || board[0][0] == -1 && board[1][1] == -1 && board[2][2] == -1 || board[0][2] == -1 && board[1][1] == -1 && board[2][0] == -1 ) //穷举的对角线
{
if (board[0][0] == 1 && board[1][1] == 1 && board[2][2] == 1 || board[0][2] == 1 && board[1][1] == 1 && board[2][0] == 1) return 1;
if (board[0][0] == -1 && board[1][1] == -1 && board[2][2] == -1 || board[0][2] == -1 && board[1][1] == -1 && board[2][0] == -1) return 2;
}
/*平局的情况*/
if (step == 9) return 3;
}
if (play_mode == 1) //人机对战模式下的判断
{
int i;
/*赢局、输局的情况(◆与★)*/
for (i = 0; i < 3; ++i) //行
if (board[i][0] == 1 && board[i][1] == 1 && board[i][2] == 1 || board[i][0] == -1 && board[i][1] == -1 && board[i][2] == -1) break; //穷举行
if (i == 3) --i;
if (board[i][0] == 1 && board[i][1] == 1 && board[i][2] == 1) return 1;
if (board[i][0] == -1 && board[i][1] == -1 && board[i][2] == -1) return 2;
/*-----------------------------*/
for (i = 0; i < 3; ++i) //列
if (board[0][i] == 1 && board[1][i] == 1 && board[2][i] == 1 || board[0][i] == -1 && board[1][i] == -1 && board[2][i] == -1) break; //穷举列
if (i == 3) --i;
if (board[0][i] == 1 && board[1][i] == 1 && board[2][i] == 1) return 1;
if (board[0][i] == -1 && board[1][i] == -1 && board[2][i] == -1) return 2;
/*-----------------------------*/
//if (board[0][0]==board[1][1]==board[2][2] && board[0][0]!=0 && board[1][1]!=0 && board[2][2]!=0 || board[0][2]==board[1][1]==board[2][0] && board[0][2] != 0 && board[1][1] != 0 && board[2][0] != 0) //对角线
if (board[0][0] == 1 && board[1][1] == 1 && board[2][2] == 1 || board[0][2] == 1 && board[1][1] == 1 && board[2][0] == 1 || board[0][0] == -1 && board[1][1] == -1 && board[2][2] == -1 || board[0][2] == -1 && board[1][1] == -1 && board[2][0] == -1) //穷举的对角线
{
if (board[0][0] == 1 && board[1][1] == 1 && board[2][2] == 1 || board[0][2] == 1 && board[1][1] == 1 && board[2][0] == 1) return 1;
if (board[0][0] == -1 && board[1][1] == -1 && board[2][2] == -1 || board[0][2] == -1 && board[1][1] == -1 && board[2][0] == -1) return 2;
}
/*平局的情况*/
if (step == 9) return 3;
}
return 0;
}
用C语言实现井字棋(人人/AI人机)--完结版的更多相关文章
- 井字棋小游戏(C语言)
最近沉迷于<NetHack>.<DCSS>等字符游戏,对其很感兴趣,于是用C语言写了个字符界面的井字棋小游戏.欢迎大家指教. 编写时遇到了一些问题,我原先准备用循环,直到读取到 ...
- 程序设计入门—Java语言 第五周编程题 2井字棋(5分)
2 井字棋(5分) 题目内容: 嗯,就是视频里说的那个井字棋.视频里说了它的基本思路,现在,需要你把它全部实现出来啦. 你的程序先要读入一个整数n,范围是[3,100],这表示井字棋棋盘的边长.比如n ...
- python 井字棋(Tic Tac Toe)
说明 用python实现了井字棋,整个框架是本人自己构思的,自认为比较满意.另外,90%+的代码也是本人逐字逐句敲的. minimax算法还没完全理解,所以参考了这里的代码,并作了修改. 特点 可以选 ...
- [CareerCup] 17.2 Tic Tac Toe 井字棋游戏
17.2 Design an algorithm to figure out if someone has won a game oftic-tac-toe. 这道题让我们判断玩家是否能赢井字棋游戏, ...
- quick cocos2d-x 入门---井字棋
学习quick cocos2d-x 第二天 ,使用quick-x 做了一个井字棋游戏 . 我假设读者已经 http://wiki.quick-x.com/doku.php?id=zh_cn阅读了这个链 ...
- [C++] 井字棋游戏源码
TicTac.h #define EX 1 //该点左鼠标 #define OH 2 //该点右鼠标 class CMyApp : public CWinApp { public: virtual B ...
- [游戏学习22] MFC 井字棋 双人对战
>_<:太多啦,感觉用英语说的太慢啦,没想到一年做的东西竟然这么多.....接下来要加速啦! >_<:注意这里必须用MFC和前面的Win32不一样啦! >_<:这也 ...
- TicTacToe井字棋 by reinforcement learning
对于初学强化学习的同学,数学公式也看不太懂, 一定希望有一些简单明了的代码实现加强对入门强化学习的直觉认识,这是一篇初级入门代码, 希望能对你们开始学习强化学习起到基本的作用. 井字棋具体玩法参考百度 ...
- 井字棋(Tic-Tac-Toe)
井字棋介绍:https://en.wikipedia.org/wiki/Tic-tac-toe 井字棋简单,但是获胜策略却和直觉不同,四角比中间重要性要高,而且先手有很大的获胜概率获胜(先手胜:91, ...
随机推荐
- ABP源码分析 - 约定注册(2)
比较随意,记录下过程,以便忘了以后重拾. 所谓约定注册是指不需要明确写代码注入,只需要按约定规则写服务类,框架自动完成服务注册. 例如,只要这样写,框架就会自动注册. public class Tax ...
- 看完这篇文章你就可以告诉领导你精通Zookeeper了
一.Zookeeper概述 1.概述 Zookeeper 是一个开源的为分布式框架提供协调服务的 Apache 项目.在分布式系统中,扮演注册中心的角色. Zookeeper数据模型的结构与Linux ...
- Spring Boot 使用 Redis 共享 Session 代码示例
参考资料 博客:spring boot + redis 实现session共享 1. 新建 Maven 工程 我新建 spring-boot-session-redis maven 工程 2. 引入 ...
- Blazor 使用拖放(drag and drop)上传文件
在很多上传文件的应用实例中, 都可以看到[拖放文件到此上传]这种骚功能 ,今天我们就来试试Blazor能不能完成这个想法. 简述HTML5拖放 拖放是HTML5标准的一部分,任何元素都能够拖放,也能够 ...
- 群晖下虚拟机编译部署WOW服务端TrinityCore
前言 前几天突然想玩WOW了,但是我是一个特别轻度的玩家,以前点卡的时候,我就是上去一个人做做任务,跑跑地图,不怎么玩副本和PVP,现在让我花钱充月卡,不太现实,没那个时间玩,所以,就考虑玩个私服,但 ...
- Postman+newman+jenkins+git实战
一.接口分类,流程,用例设计 接口分类: 外部接口:被测系统与外部其他系统之间的接口. 承保系统(被测系统),核算系统. 内部接口:被测系统内部各个子模块之间的接口. 承保系统(A模块,B模块) 测试 ...
- go 中 select 源码阅读
深入了解下 go 中的 select 前言 1.栗子一 2.栗子二 3.栗子三 看下源码实现 1.不存在 case 2.select 中仅存在一个 case 3.select 中存在两个 case,其 ...
- 十分钟学会Golang开发gRPC服务
gRPC是Google发起的一个开源RPC框架,使用HTTP/2传输协议,使用Protocol Buffers编码协议,相比RESTful框架的程序性能提高不少,而且当前流行的编程语言基本都已经支持. ...
- 【FAQ】HMS Core广告服务:如何获取正式广告位ID以及流量变现的受限情况
HMS Core广告服务开发指南中提到"xxxx为测试专用的广告位ID,App正式发布时需要改为正式的广告位ID",那么今天咱们就来说说,怎么获取正式的广告位ID. 测试广告位ID ...
- ONNX Runtime 源码阅读:Graph::SetGraphInputsOutputs() 函数
目录 前言 正文 总结 前言 为了深入理解ONNX Runtime的底层机制,本文将对 Graph::SetGraphInputsOutputs() 的代码逐行分析. 正文 首先判断Graph是否从O ...