三子棋的实现,人工智能与人工智障
Posted 小比特。。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三子棋的实现,人工智能与人工智障相关的知识,希望对你有一定的参考价值。
1.菜单
我们先进行菜单打印的实现,如下:
void menu()
printf("**********************************************\\n");
printf("************ 1.play ************\\n");
printf("************ 0.exit ************\\n");
printf("**********************************************\\n");
菜单要求我们进行输出1/0,但是我们要考虑玩家可能输错的情况所以我们用switch语句来对玩家的输入进行一个反馈,如下:
int input = 0;
do
menu();
printf("请输入(1/0):");
scanf("%d", &input);
switch (input)
case 1:
printf("开始游戏\\n");
game();
break;
case 0:
printf("退出游戏\\n");
break;
default:
printf("输入错误,请重新输入\\n");
break;
while (input);
上面这段代码是在主函数中实现的,当然你也可将其打包到一个函数中,这里就不做展示了。
当玩家输入1时,进入游戏,下面我们来实现game里的内容。
2.初始化棋盘与打印棋盘
玩家要想玩三子棋首先肯定要有一个棋盘,三子棋的棋盘一共有9个空位,玩家将在这些空位上下棋,在游戏的过程中,我们是需要对玩家和电脑的下棋情况进行收录的,所以我们先创建一个数组,在里面全部初始化为 空格 ,实现如下:
void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盘
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
board[i][j] = ' ';
void game()
int ret = 1;
int n = 0;
char board[ROW][COL] = 0 ;
InitBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
这里要说明一下,ROW代表的是行,COL代表的是列,这是提前用define设置好的,后面会提到,row和col也是一样的意思,传过来是为了方便。
之后是打印棋盘,思路其实还是蛮简单的,循环加判断,相信大家都是可以理解的,就不细说明了,实现如下:
void DisplayBoard(char board[ROW][COL], int row, int col)//打印棋盘
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
//“ |”这是一次循环
//当打印最后一次时不打印“|”
//打印出来是 | |
printf("\\n");
if (i < row - 1)
for (j = 0; j < col; j++)
printf("---");
if (j < col - 1)
printf("|");//“---|”是一次循环
//打印最后一次时不打印“|”
//打印出来是---|---|---
printf("\\n");// 上面的两行加一起是一次循环
//最后一次循环不打印---|
//打印出来是这样的效果
// | |
//---|---|---
// | |
//---|---|---
// | |
而设置ROW和COL的目的就是将棋盘的打印变得可控,可以操控棋盘的大小。
3.玩家下棋和电脑下棋
玩家下棋很简单,玩家输入坐标(1~3)(1~3)后判断此位置是否有棋子,如果有则让其在输入一次,如果没有则记录下来,放到之前创建的数组board里。
void PlayMove(char board[ROW][COL], int row, int col)//玩家下棋
int x, y;
printf("玩家输入\\n");
while (1)
printf("请输入坐标:");
scanf("%d %d", &x, &y);
if (x > 0 && x <= row && y > 0 && y <= col&&board[x - 1][y - 1] == ' ')
board[x - 1][y - 1] = '*';
break;
else if (x <= 0 || x > row || y <= 0 || y > col)
printf("坐标非法,请重新输入\\n");
else if (board[x - 1][y - 1] != ' ')
printf("该坐标已被占用,请选择其他坐标\\n");
电脑下棋我们将简单模式设置为随机下棋,下面是实现:
void ComputerMove0(char board[ROW][COL], int row, int col)
Sleep(200);
printf("电脑下棋\\n");
int x, y;
while (1)
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] == ' ')
board[x][y] = '#';
break;
随机数的概念在《猜数字游戏》这篇博客里有说,这里就不细说明了。
简单的人机肯定不是我们想要的,那么复杂的人机该怎么实现呢?
很简单,三子棋玩的好的小伙伴们都知道,如果双方都是高手在不出失误的情况下是只能平局的,实现起来也好办,把情况都列举出来就好了,但是这样不仅玩家没有良好的游戏体验,代码也繁重,所以我们仅让电脑判断:
(下面是按照优先序排列的)
1)如果己方(电脑)在横排、竖排、斜排已有两个棋子,如果剩下的位置没有棋子,则下在此处
2)如果对方(玩家)在横排、竖排、斜排已有两个棋子,如果剩下的位置没有棋子,则下在此处
3)如果以上情况都没有那么中间优先下,没有则下四角,如果都没有空位,那么随机下。
下面是实现:
int ComputerMove1(char board[ROW][COL], int row, int col)
int i = 0, j = 0, m = 1,n = 1;
printf("电脑输入\\n");
while(i < row)//判断电脑是否有两个
if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == ' ')
board[i][2] = '#';
return 1;
if (board[i][0] == '#' && board[i][2] == '#' && board[i][1] == ' ')
board[i][1] = '#';
return 1;
if (board[i][1] == '#' && board[i][2] == '#' && board[i][0] == ' ')
board[i][0] = '#';
return 1;
if (board[0][j] == '#' && board[1][j] == '#' && board[2][j] == ' ')
board[2][j] = '#';
return 1;
if (board[0][j] == '#' && board[2][j] == '#' && board[1][j] == ' ')
board[1][j] = '#';
return 1;
if (board[1][j] == '#' && board[2][j] == '#' && board[0][j] == ' ')
board[0][j] = '#';
return 1;
i++;
j++;
i = 0;
j = 0;
while (i < col)//判断玩家是否有两个
if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == ' ')
board[i][2] = '#';
return 1;
if (board[i][0] == '*' && board[i][2] == '*' && board[i][1] == ' ')
board[i][1] = '#';
return 1;
if (board[i][1] == '*' && board[i][2] == '*' && board[i][0] == ' ')
board[i][0] = '#';
return 1;
if (board[0][j] == '*' && board[1][j] == '*' && board[2][j] == ' ')
board[2][j] = '#';
return 1;
if (board[0][j] == '*' && board[2][j] == '*' && board[1][j] == ' ')
board[1][j] = '#';
return 1;
if (board[1][j] == '*' && board[2][j] == '*' && board[0][j] == ' ')
board[0][j] = '#';
return 1;
i++;
j++;
if (board[1][1] == ' ')//中间
board[1][1] = '#';
return 1;
else if (board[1][1] != ' ')//四角
if (board[0][0] == ' ')
board[0][0] = '#';
return 1;
else if (board[0][2] == ' ')
board[0][2] = '#';
return 1;
else if (board[2][0] == ' ')
board[2][0] = '#';
return 1;
else if (board[2][2] == ' ')
board[2][2] = '#';
return 1;
else//随机
int x, y;
while (1)
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] == ' ')
board[x][y] = '#';
break;
return 1;
这样一个困难的电脑就产生了。
4.判断输赢
我们需要在每次下棋(玩家或电脑)后进行判断输赢,如果玩家有三颗棋子连在一起,则玩家赢,如果电脑有三颗连在一起则电脑赢,如果棋盘满了也没有输赢则平局。
如果赢了或者平局则返回0,在game里判断是否返回0,如果是则结束本场游戏
下面是实现:
InitBoard(board, ROW, COL);//初始化棋盘
DisplayBoard(board, ROW, COL);//打印棋盘
while (1)
PlayMove(board, ROW, COL);//玩家下棋
DisplayBoard(board, ROW, COL);//打印棋盘
ret = who_win(board, ROW, COL);//判断输赢
if (ret == 0)
break;
ComputerMove0(board, ROW, COL);//电脑下棋
DisplayBoard(board, ROW, COL);//打印棋盘
ret = who_win(board, ROW, COL);//判断输赢
if (ret == 0)
break;
int who_win(char board[ROW][COL],int row, int col)
int i, j, count = 0;
for (i = 0; i < row; i++)
if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == '*')
printf("玩家赢\\n");
Sleep(2000);
system("cls");
return 0;
if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == '#')
printf("电脑赢\\n");
Sleep(2000);
system("cls");
return 0;
for (i = 0; i < col; i++)
if (board[0][i] == '*' && board[1][i] == '*' && board[2][i] == '*')
printf("玩家赢\\n");
Sleep(2000);
system("cls");
return 0;
if (board[0][i] == '#' && board[1][i] == '#' && board[2][i] == '#')
printf("电脑赢\\n");
Sleep(2000);
system("cls");
return 0;
if ((board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*') || (board[0][2] == '*' && board[1][1] == '*' && board[2][0] == '*'))
printf("玩家赢\\n");
Sleep(2000);
system("cls");
return 0;
if ((board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#') || (board[0][2] == '#' && board[1][1] == '#' && board[2][0] == '#'))
printf("电脑赢\\n");
Sleep(2000);
system("cls");
return 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
if (board[i][j] != ' ')
count++;
if (count == row * col)
printf("平局了\\n");
Sleep(2000);
system("cls");
return 0;
return 1;
还有难度的选择,判断即可,下面是源代码(我是分文件写的):
主文件:
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
printf("**********************************************\\n");
printf("************ 1.play ************\\n");
printf("************ 0.exit ************\\n");
printf("**********************************************\\n");
void game()
int ret = 1;
int n = 0;
char board[ROW][COL] = 0 ;
printf("请选择难度(0.简单/1.困难):");
scanf("%d", &n);
if (n == 0)
InitBoard(board, ROW, COL);//初始化棋盘
DisplayBoard(board, ROW, COL);//打印棋盘
while (1)
PlayMove(board, ROW, COL);//玩家下棋
DisplayBoard(board, ROW, COL);//棋盘
ret = who_win(board, ROW, COL);//判断输赢
if (ret == 0)
break;
ComputerMove0(board, ROW, COL);//电脑下棋
DisplayBoard(board, ROW, COL);//棋盘
ret = who_win(board, ROW, COL);//判断输赢
if (ret == 0)
break;
else if (n == 1)
InitBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
while (1)
PlayMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = who_win(board, ROW, COL);
if (ret == 0)
break;
ComputerMove1(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = who_win(board, ROW, COL);
if (ret == 0)
break;
else
printf("输入错误,默认选简单\\n");
InitBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
while (1)
PlayMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = who_win(board, ROW, COL);
if (ret == 0)
break;
ComputerMove0(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = who_win(board, ROW, COL);
if (ret == 0)
break;
int main()
srand((unsigned int)time(NULL));
int input = 0;
do
menu();
printf("请输入(1/0):");
scanf("%d", &input);
switch (input)
case 1:
printf("开始游戏\\n");
game();
break;
case 0:
printf("退出游戏\\n");
break;
default:
printf("输入错误,请重新输入\\n");
break;
while (input);
return 0;
game.h头文件:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define ROW 3
#define COL 3
void InitBoard(char board[ROW][COL], int row, int col);
void DisplayBoard(char board[ROW][COL], int row, int col);
void PlayMove(char board[ROW][COL], int row, int col);
void ComputerMove0(char board[ROW][COL], int row, int col);
int ComputerMove1(char board[ROW][COL], int row, int col);
int who_win(char board[ROW][COL], int row, int col);
game.cpp存放函数实现的文件:
#include "game.h"
void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盘
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
board[i][j] = ' ';
void DisplayBoard(char board[ROW][COL], int row, int col)//打印棋盘
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
printf("\\n");
if (i < row - 1)
for (j = 0; j < col; j++)
printf("---");
if (j < col - 1)
printf("|");
printf("\\n");
void PlayMove(char board[ROW][COL], int row, int col)//玩家下棋
int x, y;
printf("玩家输入\\n");
while (1)
printf("请输入坐标:");
scanf("%d %d", &x, &y);
if (x > 0 && x <= row && y > 0 && y <= col&&board[x - 1][y - 1] == ' ')
board[x - 1][y - 1] = '*';
break;
else if (x <= 0 || x > row || y <= 0 || y > col)
printf("坐标非法,请重新输入\\n");
else if (board[x - 1][y - 1] != ' ')
printf("该坐标已被占用,请选择其他坐标\\n");
void ComputerMove0(char board[ROW][COL], int row, int col)//简单电脑
Sleep(200);
printf("电脑下棋\\n");
int x, y;
while (1)
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] == ' ')
board[x][y] = '#';
break;
int ComputerMove1(char board[ROW][COL], int row, int col)//困难电脑
int i = 0, j = 0, m = 1,n = 1;
printf("电脑输入\\n");
while(i < row)
if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == ' ')
board[i][2] = '#';
return 1;
if (board[i][0] == '#' && board[i][2] == '#' && board[i][1] == ' ')
board[i][1] = '#';
return 1;
if (board[i][1] == '#' && board[i][2] == '#' && board[i][0] == ' ')
board[i][0] = '#';
return 1;
if (board[0][j] == '#' && board[1][j] == '#' && board[2][j] == ' ')
board[2][j] = '#';
return 1;
if (board[0][j] == '#' && board[2][j] == '#' && board[1][j] == ' ')
board[1][j] = '#';
return 1;
if (board[1][j] == '#' && board[2][j] == '#' && board[0][j] == ' ')
board[0][j] = '#';
return 1;
i++;
j++;
i = 0;
j = 0;
while (i < col)
if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == ' ')
board[i][2] = '#';
return 1;
if (board[i][0] == '*' && board[i][2] == '*' && board[i][1] == ' ')
board[i][1] = '#';
return 1;
if (board[i][1] == '*' && board[i][2] == '*' && board[i][0] == ' ')
board[i][0] = '#';
return 1;
if (board[0][j] == '*' && board[1][j] == '*' && board[2][j] == ' ')
board[2][j] = '#';
return 1;
if (board[0][j] == '*' && board[2][j] == '*' && board[1][j] == ' ')
board[1][j] = '#';
return 1;
if (board[1][j] == '*' && board[2][j] == '*' && board[0][j] == ' ')
board[0][j] = '#';
return 1;
i++;
j++;
if (board[1][1] == ' ')
board[1][1] = '#';
return 1;
else if (board[1][1] != ' ')
if (board[0][0] == ' ')
board[0][0] = '#';
return 1;
else if (board[0][2] == ' ')
board[0][2] = '#';
return 1;
else if (board[2][0] == ' ')
board[2][0] = '#';
return 1;
else if (board[2][2] == ' ')
board[2][2] = '#';
return 1;
else
int x, y;
while (1)
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] == ' ')
board[x][y] = '#';
break;
return 1;
int who_win(char board[ROW][COL],int row, int col)//判断输赢
int i, j, count = 0;
for (i = 0; i < row; i++)
if (board[i][0] == '*' && board[i][1] == '*' && board[i][2] == '*')
printf("玩家赢\\n");
Sleep(2000);
system("cls");
return 0;
if (board[i][0] == '#' && board[i][1] == '#' && board[i][2] == '#')
printf("电脑赢\\n");
Sleep(2000);
system("cls");
return 0;
for (i = 0; i < col; i++)
if (board[0][i] == '*' && board[1][i] == '*' && board[2][i] == '*')
printf("玩家赢\\n");
Sleep(2000);
system("cls");
return 0;
if (board[0][i] == '#' && board[1][i] == '#' && board[2][i] == '#')
printf("电脑赢\\n");
Sleep(2000);
system("cls");
return 0;
if ((board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*') || (board[0][2] == '*' && board[1][1] == '*' && board[2][0] == '*'))
printf("玩家赢\\n");
Sleep(2000);
system("cls");
return 0;
if ((board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#') || (board[0][2] == '#' && board[1][1] == '#' && board[2][0] == '#'))
printf("电脑赢\\n");
Sleep(2000);
system("cls");
return 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
if (board[i][j] != ' ')
count++;
if (count == row * col)
printf("平局了\\n");
Sleep(2000);
system("cls");
return 0;
return 1;
以上就是三子棋的全部内容了。
以上是关于三子棋的实现,人工智能与人工智障的主要内容,如果未能解决你的问题,请参考以下文章