目录
前言
三子棋的棋盘是一个九宫格,双方轮流落子,若有一方横竖或者对角线有三个棋子连成一条直线则胜利。但是三子棋有很多种和棋情况。
一、基本思路流程介绍
1.创建一个用户交互菜单
2.创建一个棋盘并初始化
3.打印一个棋盘
4.玩家落子
5.判定胜负关系
6.电脑落子
7.判定胜负关系
8.结束
二、代码实现
1.用户交互菜单(Menu函数)
void Menu()
{
printf("|---------------------------|\n");
printf("|******* 1. play ********|\n");
printf("|******* 0. exit ********|\n");
printf("|---------------------------|\n");
}
2.初始化棋盘(InitBoard函数)
void InitBoard(char board[ROW][COL], int row, int col) //初始化棋盘
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{ //使用一个二维数组初始化棋盘
board[i][j] = INIT; //全部设置为INIT宏定义的空格
}
}
}
我们的棋盘实际上是一个二维数组,初始化过程实际上就是使用了一个双重for循环,给每一个数组的元素赋值为空格。
3.打印棋盘(ShowBoard函数)
void ShowBoard(char board[ROW][COL], int row, int col) //展示棋盘
{
system("cls"); //调用dos命令窗口进行清屏操作,即刷新棋盘
printf(" ");
for (int i = 0; i < col; i++)
{
printf("%4d", i + 1);
}
printf("\n--+---+---+---\n");
for (int i = 0; i < row; i++)
{
printf("%-2d", i + 1); //2
for (int j = 0; j < col; j++)
{
printf("| %c ", board[i][j]); //12
}
printf("\n--+---+---+---\n");
}
}
4.玩家落子(PlayerMove函数)
void PlayerMove(char board[ROW][COL], int row, int col) //人选择落子位置
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入你想落子的位置坐标x y:>");
scanf("%d %d", &y, &x);
if (x < 1 || x>3 || y < 1 || y>3)
{ //非法性判断,因为棋盘为3x3
printf("超出了棋盘范围,请重新输入!");
continue;
}
if (board[x - 1][y - 1] == INIT)
{ //只有当这个格子为空的时候才可以落子
board[x - 1][y - 1] = WHITE; //落下的棋子为白子
break;
}
else
{
printf("此格子已被占用,请从新输入");
}
}
}
5.电脑落子(ComputerMove函数)
void ComputerMove(char board[ROW][COL], int row, int col) //电脑自动落子
{
while (1)
{
int x = rand() % 3; //生成的随机数对三取余,生成的数字只可能为0,1,2
int y = rand() % 3;
if (board[x][y] == INIT)
{
board[x][y] = BLACK;
break;
}
}
}
6.判定胜负关系(IsEnd函数)
char IsEnd(char board[ROW][COL], int row, int col) //判断结果
{
for (int i = 0; i < row; i++)
{ //判定所有列是否有三个相同的棋子
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && \
board[i][0] != INIT) //\为续行符
{
return board[i][0]; //此位置的返回值为WHITE或者BLACK
}
}
for (int j = 0; j < col; j++)
{ //判定所有行是否有三个相同的棋子
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && \
board[0][j] != INIT) //\为续行符
{
return board[0][j]; //此位置的返回值为WHITE或者BLACK
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && \
board[1][1] != INIT) //判定对角线是否有三个棋子相等
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && \
board[1][1] != INIT) //判定对角线是否有三个棋子相等
{
return board[1][1];
}
for (int i = 0; i < row; i++)
{ //判断棋盘是否满了,若不满则继续游戏
for (int j = 0; j < col; j++)
{
if (board[i][j] == INIT)
{
return NEXT;
}
}
}
return DRAW; //上述所有情况都不满足,则为平局
}
7.Game()函数
void Game()
{
char board[ROW][COL]; //定义棋盘
char result = 0;
srand((unsigned long)time(NULL)); //生成随机数种子
InitBoard(board, ROW, COL); //初始化棋盘
while (1)
{
ShowBoard(board, ROW, COL); //展示棋盘
PlayerMove(board, ROW, COL); //人开始选择落子位置
result = IsEnd(board, ROW, COL); //判断游戏结果,若结果不是继续则退出。
if (result != NEXT)
{
break;
}
ShowBoard(board, ROW, COL); //展示棋盘
ComputerMove(board, ROW, COL); //电脑随机落子
result = IsEnd(board, ROW, COL); //断游戏结果,若结果不是继续则退出。
if (result != NEXT)
{
break;
}
}
ShowBoard(board, ROW, COL); //展示棋盘
switch (result)
{ //判断棋局结果
case WHITE:
printf("你赢了!\n\n");
break;
case BLACK:
printf("你输了\n\n");
break;
case DRAW:
printf("平局啦!\n\n");
default:
break;
}
}
三、总代码
#include<stdio.h>
#include<Windows.h>
#include<time.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
#define INIT ' ' //宏定义初始化输入的值为空
#define WHITE 'X'//白方是Player 棋子为X
#define BLACK 'O'//黑方是Computer 棋子为O
#define DRAW 'D'//
#define NEXT 'N'//
void InitBoard(char board[][COL], int row, int col); //初始化棋盘
void ShowBoard(char board[][COL], int row, int col); //打印棋盘
char IsEnd(char board[][COL], int row, int col); //判断是否结束
void ComputerMove(char board[][COL], int row, int col); //电脑下棋
void PlayerMove(char board[][COL], int row, int col); //玩家下棋
#include "game.h"
void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盘
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{ //使用一个二维数组初始化棋盘
board[i][j] = INIT; //全部设置为INIT宏定义的空格
}
}
}
void ShowBoard(char board[ROW][COL], int row, int col)
{ //展示棋盘
system("cls"); //调用dos命令窗口进行清屏操作,即刷新棋盘
printf(" ");
for (int i = 0; i < col; i++)
{
printf("%4d", i + 1);
}
printf("\n--+---+---+---\n");
for (int i = 0; i < row; i++)
{
printf("%-2d", i + 1); //2
for (int j = 0; j < col; j++)
{
printf("| %c ", board[i][j]); //12
}
printf("\n--+---+---+---\n");
}
}
void PlayerMove(char board[ROW][COL], int row, int col) //人选择落子位置
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入你想落子的位置坐标x y:>");
scanf("%d %d", &y, &x);
if (x < 1 || x>3 || y < 1 || y>3)
{ //非法性判断,因为棋盘为3x3
printf("超出了棋盘范围,请重新输入!");
continue;
}
if (board[x - 1][y - 1] == INIT)
{ //只有当这个格子为空的时候才可以落子
board[x - 1][y - 1] = WHITE; //落下的棋子为白子
break;
}
else
{
printf("此格子已被占用,请从新输入");
}
}
}
void ComputerMove(char board[ROW][COL], int row, int col) //电脑自动落子
{
while (1)
{
int x = rand() % 3; //生成的随机数对三取余,生成的数字只可能为0,1,2
int y = rand() % 3;
if (board[x][y] == INIT)
{
board[x][y] = BLACK;
break;
}
}
}
char IsEnd(char board[ROW][COL], int row, int col) //判断结果
{
for (int i = 0; i < row; i++)
{ //判定所有列是否有三个相同的棋子
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != INIT) //\为续行符
{
return board[i][0]; //此位置的返回值为WHITE或者BLACK
}
}
for (int j = 0; j < col; j++)
{ //判定所有行是否有三个相同的棋子
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != INIT) //\为续行符
{
return board[0][j]; //此位置的返回值为WHITE或者BLACK
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && //判定对角线是否有三个棋子相等
board[1][1] != INIT)
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && //判定对角线是否有三个棋子相等
board[1][1] != INIT)
{
return board[1][1];
}
for (int i = 0; i < row; i++)
{ //判断棋盘是否满了,若不满则继续游戏
for (int j = 0; j < col; j++)
{
if (board[i][j] == INIT)
{
return NEXT;
}
}
}
return DRAW; //上述所有情况都不满足,则为平局
}
void Game()
{
char board[ROW][COL]; //定义棋盘
char result = 0;
srand((unsigned long)time(NULL)); //生成随机数种子
InitBoard(board, ROW, COL); //初始化棋盘
while (1)
{
ShowBoard(board, ROW, COL); //展示棋盘
PlayerMove(board, ROW, COL); //人开始选择落子位置
result = IsEnd(board, ROW, COL); //判断游戏结果,若结果不是继续则退出。
if (result != NEXT)
{
break;
}
ShowBoard(board, ROW, COL); //展示棋盘
ComputerMove(board, ROW, COL); //电脑随机落子
result = IsEnd(board, ROW, COL); //断游戏结果,若结果不是继续则退出。
if (result != NEXT)
{
break;
}
}
ShowBoard(board, ROW, COL); //展示棋盘
switch (result)
{ //判断棋局结果
case WHITE:
printf("你赢了!\n\n");
break;
case BLACK:
printf("你输了\n\n");
break;
case DRAW:
printf("平局啦!\n\n");
default:
break;
}
}
void Menu()
{
printf("|---------------------------|\n");
printf("|******* 1. play ********|\n");
printf("|******* 0. exit ********|\n");
printf("|---------------------------|\n");
}
int main()
{
int select = 0; //输入选择
int quit = 0; //控制循环结束
while (!quit)
{
Menu();
printf("1开始 或 0退出 请选择:> ");
scanf("%d", &select);
switch (select)
{
case 1: //选择1则开始游戏
Game();
break;
case 0: //选择0则退出游戏
quit = 1;
break;
default:
printf("输入格式错误,请重新输入。\n");
break;
}
}
system("pause");
}