一、问题的描述
用c语言实现三子棋游戏
二、基本逻辑
2.1要用代码实现三子棋,我们可以从两个方面入手,一是游戏的整体逻辑,二是游戏的实现逻辑即游戏的主体
2.2游戏的整体逻辑我们创建game.h,game.c,test.c来分模块实现
2.3游戏的实现逻辑包括以下几部分:
1.棋盘的初始化:
(1)空棋盘的初始化
(2)棋盘的打印
2.下棋步骤
(1)玩家下棋
(2)判断输赢
(3)打印棋盘
(4)电脑下棋
(5)判断输赢
(6)打印棋盘
三、游戏的实现
3.1游戏菜单
创建游戏菜单,1.开始游戏,0.退出游戏,其他输入重新进行选择,我们用while循环来实现这一功能
int main()
{
int input = 0;
srand((unsigned int)time(NULL)); //随机数的生成起点
do
{
menu();
printf("请输入你的选择:\n");
scanf("%d", &input);
switch (input)
{
case 1:
{
printf("三子棋游戏开始\n");
game(); //游戏主体
break;
}
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input); //游戏的多次实现
return 0;
}
3.2初始化空棋盘
//初始化棋盘
void Initkeyboard(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.3棋盘的打印
要注意分隔符的打印次数
//打印棋盘
void Displaykeyboard(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 < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
3.4玩家下棋
玩家下棋要注意:所下位置是否在合法范围内,所下位置是否为空,若都不满足,重新输入。
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋,请输入坐标位置:\n");
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] = 'x';
break;
}
else
{
printf("输入位置被占!请重新输入坐标!\n");
}
}
else
{
printf("输入非法,请重新输入坐标!\n");
}
}
3.5电脑下棋
电脑下棋要在主函数里面使用随机数生成种子srand(),保证随机数的生成起点
电脑下棋要选择有空位的地方下棋
//电脑下棋
//选择有空位的地方下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋\n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = 'o';
break;
}
}
}
3.6判断胜负
1.返回结果的约定
若返回为'x',则玩家赢
若返回为'o',则电脑赢
若返回为'Q',则平局
若返回为'C',则游戏继续
在游戏主体函数里判断输赢
void game()
{
char ret1 = 0;
char ret2 = 0;
char ret = 0;
char board[ROW][COL] = { 0 };
//初始化棋盘
Initkeyboard(board, ROW, COL);
//打印棋盘
Displaykeyboard(board, ROW, COL);
//下棋
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
//判断输赢
char ret1=IsWin(board, ROW, COL);
ret = ret1;
if (ret1 != 'C')
{
break;
}
Displaykeyboard(board, ROW, COL);
电脑下棋
ComputerMove(board, ROW, COL);
//判断输赢
char ret2 = IsWin(board, ROW, COL);
ret = ret2;
if (ret2 != 'C')
{
break;
}
Displaykeyboard(board, ROW, COL);
}
if (ret == 'x')
{
printf("玩家赢了\n");
}
else if (ret == 'o')
{
printf("电脑赢了\n");
}
else
{
printf("平局\n");
}
printf("最终棋面为\n");
Displaykeyboard(board, ROW, COL);
}
2.判断是否满盘Full()
//判断是否满盘
//满盘 返回1
//不满盘 返回0
int 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;
}
3.判断输赢的实现
分为行和棋,列和棋,对角线和棋
//判断输赢
char IsWin(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
//行相等
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][1];
}
}
//列相等
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
{
return board[1][j];
}
}
//对角线相等
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 (Full(board, ROW, COL))
{
return 'Q';
}
return 'C';
}
四、游戏实现结果
五、代码的总体实现
5.1game.h
使用该模块时要包含头文件#include "game.h"
使用宏定义的原因:
推高代码可读性,后续代码中遇到3,方便理解含义
提高扩展性,如果将来要修改棋盘尺寸,代码修改会很方便
#pragma once
#include<stdio.h>
#define ROW 3
#define COL 3
#include<stdlib.h>
#include<time.h>
//初始化棋盘
void Initkeyboard(char board[ROW][COL],int row,int col);
//打印棋盘
void Displaykeyboard( char board[ROW][COL],int row,int col);
//玩家下棋
void PlayerMove(char board[ROW][COL],int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL],int row,int col);
//判断输赢
//玩家赢 'x'
//电脑赢 'o'
//平局 'Q'
//继续游戏 'C'
char IsWin(char board[ROW][COL], int row, int col);
5.2game.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
//初始化棋盘
void Initkeyboard(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 Displaykeyboard(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 < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋,请输入坐标位置:\n");
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] = 'x';
break;
}
else
{
printf("输入位置被占!请重新输入坐标!\n");
}
}
else
{
printf("输入非法,请重新输入坐标!\n");
}
}
}
//电脑下棋
//选择有空位的地方下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋\n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = 'o';
break;
}
}
}
//判断是否满盘
//满盘 返回1
//不满盘 返回0
int 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 IsWin(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
//行相等
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][1];
}
}
//列相等
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
{
return board[1][j];
}
}
//对角线相等
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 (Full(board, ROW, COL))
{
return 'Q';
}
return 'C';
}
5.3test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
printf("***********************************\n");
printf("***************1.play**************\n");
printf("***************0.exit**************\n");
printf("***********************************\n");
}
void game()
{
char ret1 = 0;
char ret2 = 0;
char ret = 0;
char board[ROW][COL] = { 0 };
//初始化棋盘
Initkeyboard(board, ROW, COL);
//打印棋盘
Displaykeyboard(board, ROW, COL);
//下棋
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
//判断输赢
char ret1=IsWin(board, ROW, COL);
ret = ret1;
if (ret1 != 'C')
{
break;
}
Displaykeyboard(board, ROW, COL);
电脑下棋
ComputerMove(board, ROW, COL);
//判断输赢
char ret2 = IsWin(board, ROW, COL);
ret = ret2;
if (ret2 != 'C')
{
break;
}
Displaykeyboard(board, ROW, COL);
}
if (ret == 'x')
{
printf("玩家赢了\n");
}
else if (ret == 'o')
{
printf("电脑赢了\n");
}
else
{
printf("平局\n");
}
printf("最终棋面为\n");
Displaykeyboard(board, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL)); //随机数的生成起点
do
{
menu();
printf("请输入你的选择:\n");
scanf("%d", &input);
switch (input)
{
case 1:
{
printf("三子棋游戏开始\n");
game(); //游戏主体
break;
}
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input); //游戏的多次实现
return 0;
}