经过自己的努力终于也可以写出三子棋小游戏还是很有成就感的!
我会把完整代码放在最后。
首先我们要建立三个文件:
以方便后期维护和增加代码可读性,防止代码冗余.
game.c用来封装函数,实现各部分功能;test.c用来构建整个程序的框架;game.h用来存放所有头文件,我们只需把#include包含的头文件放在test.h文件,再在game.c 、test.c里加上#include"game.h"即可。
玩游戏首先要构建我们的框架:
第一步我们先完成菜单部分:
我们每次完成一个小的部分的时候我们可以运行测试一下看看是否有bug。不然到最后才运行可能bug很多不容易解决。
考虑到玩家玩完之后还想继续玩,所以可以构建一个do while循环的结构;既然有了菜单可选项,我们可以给程序一个输入值1和0,用switch语句进行选择。
接下来我们case 1:当我们输入1后变开始游戏,那我们就创建一个game函数完成游戏部分
我们下棋首先要有一个棋盘我们才可以下棋。我们先初始化一个棋盘
我们定义了一个三行三列的棋盘,但是这样我们要修改棋盘的时候很麻烦这里所有的数字都要修改。于是我们可以这样.
别忘记把函数声明放入game.h里噢
那我们开始写game函数,初始化打印一个棋盘。
我们其实这样打印出来的是空格那这样不行啊。 我们需要把横线加进去。
这样我们就把棋盘的效果打印出来了。
但是这样要变更多的棋格就会很麻烦修改很多,所以我们进行优化.
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
for (j = 0; j < col; j++)
{
if (i < row - 1)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
- 外层循环
i
遍历每一行。 - 内层循环
j
遍历每一列。 - 打印当前格子的值
board[i][j]
,并在格子之间打印竖线"|"
。 - 在每一行的最后一个格子后面换行。
- 第二个内层循环
j
在每一行的最后一个格子之后,根据当前行数i
和棋盘的行数row
判断是否需要打印横线和竖线。 - 打印横线
"---"
和竖线"|"
。 - 在每一行的最后一个格子后面换行。
这样棋盘就完成了,接下来就是落棋了。电脑和玩家对弈。
首先我们要设定棋子,玩家下的棋用*来表示,电脑下的棋用#号来表示。
我们下的棋格的坐标用x,y来表示。下面的代码不难理解,数组的下标是从0开始的所以我们不能小于1同时也不能超出数组的长度。我们首先判断棋格上是否为空格,否则棋有可能下重。如果为空格,我们便可以落子在棋盘上。
玩家下完棋应该电脑下棋。 这里我用了rand函数对于rand函数,我另一篇数字小游戏中有详细的说明。大家感兴趣的话可以去看看。
最后也是最关键的一步判断谁胜谁负了。
我们有三种结果玩家赢,电脑赢,平局。我们每下一步棋都要判断一次。当返回值为*就是玩家赢,当返回值是#就是电脑赢。
如果横着的三个格子里是相同的符号且不是空格那么就返回其中一个格子里的值。如果竖着的三个格子里是相同的符号且不是空格那么就返回其中一个格子里的值。如果斜着的三个格子里是相同的符号且不是空格那么就返回其中一个格子里的值。这里返回的值所对应的就是‘*’和‘#’。就能判断出胜负了。
还有判断是否平局。我们遍历每一行每一列。如果有空格的话就继续游戏。如果没有空格的话,就平局。
#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]);
// }
// printf("\n");
// }
//}
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
for (j = 0; j < col; j++)
{
if (i < row - 1)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
void PlayerMove(char board[ROW][COL], int row, int col)
{
printf("玩家下棋:\n");
int x = 0;
int y = 0;
while (1)
{
printf("请输入要下的坐标:");
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("该坐标已经占用了。");
}
}
else
{
printf("输错了,重新输入。");
}
}
}
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 - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '#';
break;
}
}
}
static int IsFull(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;
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][0];
}
}
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][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 (IsFull(board, row, col))
{
return 'Q';
}
return 'C';
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "game.h"
void menu()
{
printf("********************\n");
printf("*****1.开始游戏*****\n");
printf("*****0.退出游戏*****\n");
printf("********************\n");
}
void game()
{
char ret = 0;
char board[ROW][COL];
InitBoard(board, ROW, COL);
//初始化棋盘
DisplayBoard(board, ROW, COL);
//打印棋盘
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret=IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏。\n");
break;
default:
printf("输入错误请重新输入。\n");
}
} while (input);
return 0;
}
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.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 PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);
以上就是完整的代码了,希望大家多多支持! 感谢大家的支持。