【C语言】三子棋的实现
目录
一、理清逻辑
首先我们先来理一理三子棋实现的逻辑
1.打印游戏菜单
2.创建并初始化二维数组
3.打印棋盘
4.双方下棋
5.判断胜负
二、创建文件
我创建了三个文件,分别为test.c、game.h和game.c
test.c文件用于实现进入游戏、退出游戏、判断输赢、打印菜单等逻辑
game.c用于编写游戏的主要实现方法
game.h存放头文件和函数的声明
三、具体步骤
1.创建菜单和实现方法
写在test.c文件中
void menu()
{
printf("********************************n");
printf("********* 1.play ***********n");
printf("********* 0.exit ***********n");
printf("********************************n");
}
void test()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf(":>");
scanf("%d", &input);
switch (input)
{
case 1:
printf("三子棋游戏开始n");
game();
break;
case 0:
printf("结束游戏n");
break;
default:
printf("输入错误n");
break;
}
} while (input);
}
2.创建并初始化二维数组
在test.c中创建二维数组并引用初始化数组的方法
void game()
{
//创建二维数组
char board[ROW][COL] = { 0 };
//初始化二维数组
InitBoard(board, ROW, COL);
}
在game.h中用宏定义定义行列,声明函数,填写需要的头文件
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
在game.c中定义初始化数组的方法
#include "game.h"
void InitBoard(char board[ROW][COL],int row,int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
3.打印棋盘
在game.c中定义打印棋盘的方法,需要注意的是每打印一行后要进行换行
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
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 < row; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("n");
}
}
在test.c中game方法中引用此函数
4.双方下棋
人机双方轮流下棋,所以应该在test.c中将人机下棋的步骤放入循环
//下棋
while (1)
{
//玩家下棋
player_move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//电脑下棋
computer_move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
}
1)玩家下棋
在game.c中定义实现玩家下棋的方法,要考虑到下棋是否在范围内和位置是否重复落子的情况,
因为我们是通过二维数组来实现的,所以我们输入的坐标x,y所对应的数组下标应该是x-1,y-1
void player_move(char board[ROW][COL], int row, int col)
{
printf("玩家下棋:>");
int x = 0;
int y = 0;
while (1)
{
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
printf("该坐标被占用,请重新输入!n");
}
else
printf("坐标非法,请重新输入!n");
}
}
2)电脑下棋
在game.c中定义电脑下棋的方法,我用的是比较简单的用rand函数生成随机数来随机建立坐标,当然这个ai算法是可以优化的。
void computer_move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下棋:>n");
while (1)
{
x = rand() % ROW;
y = rand() % COL;
if (board[x][y]== ' ')
{
board[x][y] = '#';
break;
}
}
}
5.判断胜负
三子棋的结果无非就是三种,玩家赢,电脑赢,平局
我们先在game.c中定义一个实现判断结果的方法
任意一行相同或任意一列相同或对角线相同则视为胜利
//玩家赢:'*'
//电脑赢:'#'
//平局:Q
//继续:C
int is_full(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
{
return board[i][1];
}
}
for (i = 0; i < row; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[1][i];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
if (is_full(board, row, col)==1)
{
return 'Q';
}
//继续
return 'C';
}
在test.c中实现判断胜负的逻辑
char ret = 0;
while (1)
{
//玩家下棋
player_move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
//电脑下棋
computer_move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
//判断胜负
if (ret == '*')
{
printf("玩家赢了!n");
}
else if (ret == '#')
{
printf("电脑赢了!n");
}
else
{
printf("平局n");
}
}
四、运行结果
下面就来展示一下我和人工智障的精彩对局吧
嗯,看来我创造出来的ai已经强大到可以击败我了,我真厉害!
五、完整代码展示
game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.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 player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("********************************n");
printf("********* 1.play ***********n");
printf("********* 0.exit ***********n");
printf("********************************n");
}
void game()
{
//创建二维数组
char board[ROW][COL] = { 0 };
//初始化二维数组
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//下棋
char ret = 0;
while (1)
{
//玩家下棋
player_move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
//电脑下棋
computer_move(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
//判断胜负
if (ret == '*')
{
printf("玩家赢了!n");
}
else if (ret == '#')
{
printf("电脑赢了!n");
}
else
{
printf("平局n");
}
}
void test()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf(":>");
scanf("%d", &input);
switch (input)
{
case 1:
printf("三子棋游戏开始n");
game();
break;
case 0:
printf("结束游戏n");
break;
default:
printf("输入错误n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard(char board[ROW][COL],int row,int col)
{
int i = 0;
int j = 0;
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 = 0;
int j = 0;
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 < row; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("n");
}
}
void player_move(char board[ROW][COL], int row, int col)
{
printf("玩家下棋:>");
int x = 0;
int y = 0;
while (1)
{
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
printf("该坐标被占用,请重新输入!n");
}
else
printf("坐标非法,请重新输入!n");
}
}
void computer_move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下棋:>n");
while (1)
{
x = rand() % ROW;
y = rand() % COL;
if (board[x][y]== ' ')
{
board[x][y] = '#';
break;
}
}
}
int is_full(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
{
return board[i][1];
}
}
for (i = 0; i < row; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[1][i];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
if (is_full(board, row, col)==1)
{
return 'Q';
}
//继续
return 'C';
}
当然,随着所学的知识不断增加,这个游戏可以不断的被优化。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
二维码