自话:
三子棋对与一个初学c语言的同学来说,是一个即不难又考察基本功的c语言小项目.最后面有完整程序.
游戏实现后样子:
基本思路:
1.首先创建三个文件:game.h(存放游戏中头文件及函数声明)
game.c(游戏相关函数的实现)
test.c(游戏逻辑测试)
2.游戏逻辑设计:(1)有一个游戏菜单,可以实现--开始游戏--退出游戏--
(2)有一个基本棋盘,可以实现棋盘数据的存放
(3)打印棋盘,可以打印棋盘基本线格,并且可以打印棋子
(4)下棋程序--1--玩家自主下棋
--2--电脑随机下棋
(5)判断游戏进行状态--1-- 玩家赢
--2-- 电脑赢
--3-- 平局
--4-- 游戏继续
温馨提示:当你看到此处时,你可以根据上述游戏逻辑,自行完成游戏的设计.如果想直接学习具体的实现过程,可以继续往下看.
游戏实现:
(1) 创建游戏菜单
test.c
void menu()
{
printf("***************************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("***************************\n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");//为0判断为假,跳出do while 循环
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
注意:(1) 创建的 int input = 0;一定要放在do while();之外
(2) scanf("%d",&input);一定要放在do while();之内
(2) 创建基本棋盘
test.c
void game()
{
//储存数据 - 二维数组
char board[ROW][COL];
//初始化棋盘 - 初始化空格
InitBoard(board, ROW , COL);
}
void menu()
{
printf("***************************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("***************************\n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");//为0判断为假,跳出do while 循环
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
game.h
#pragma once
#include<stdio.h>
//符号的定义
#define ROW 3
#define COL 3
//函数的声明
//初始化棋盘
void InitBoard(char board[ROW][COL], int row,int col);
game.c
//初始化棋盘
void InitBoard(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++)
{
board[i][j] = ' ';
}
}
}
注意: (1) 一定要创建一个字符数组棋盘
(2)代码顺序最好按照上述的来(下面不再提示)
(3)对与参数的定义要用宏来定义(#define ROW 3) ,方便以后的修改
(4)函数名最好有实际意义(下面不再提示)
(3) 实现棋盘打印
test.c
void game()
{
//储存数据 - 二维数组
char board[ROW][COL];
//初始化棋盘 - 初始化空格
InitBoard(board, ROW , COL);
//打印一下棋盘 - 本质是打印数组的内容
DisplayBoard(board, ROW, COL);
}
void menu()
{
printf("***************************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("***************************\n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");//为0判断为假,跳出do while 循环
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
game.h
#pragma once
#include<stdio.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);
game.c
#include"game.h"
//初始化棋盘
void InitBoard(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++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
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");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("+");
}
}
}
printf("\n");
}
}
注意: 棋盘的打印的实现(图解)
(4)下棋程序--玩家自主下棋
test.c
void game()
{
//储存数据 - 二维数组
char board[ROW][COL];
//初始化棋盘 - 初始化空格
InitBoard(board, ROW , COL);
//打印一下棋盘 - 本质是打印数组的内容
DisplayBoard(board, ROW, COL);
//玩家下
PlayerMove(board,ROW,COL);
}
void menu()
{
printf("***************************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("***************************\n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");//为0判断为假,跳出do while 循环
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
game.h
#pragma once
#include<stdio.h>
#include<time.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 PlayerMove(char board[ROW][COL], int row, int col);
game.c
/初始化棋盘
void InitBoard(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++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
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");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("+");
}
}
}
printf("\n");
}
}
int x = 0;
int y = 0;
//玩家下
void PlayerMove(char board[ROW][COL], int row, int col)
{
printf("玩家走:>");
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("坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
注意:(1)scanf("%d %d",&x,&y);一定要创建到while(1)之内
(2)int x = 0;int y = 0;最好创建为全局变量,之后电脑下棋就不用创建了
(3)x与y一定要规定合法范围
(4)玩家是不了解下标的,因此需要下棋时x与y要-1
(5)下棋程序--电脑下棋
test.c
void game()
{
//储存数据 - 二维数组
char board[ROW][COL];
//初始化棋盘 - 初始化空格
InitBoard(board, ROW , COL);
//打印一下棋盘 - 本质是打印数组的内容
DisplayBoard(board, ROW, COL);
//玩家下
PlayerMove(board,ROW,COL);
//电脑下
ComputerMove(board, ROW, COL);
}
void menu()
{
printf("***************************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("***************************\n");
}
int main()
{
srand((unsigned int)time(NULL));//利用时间戳返回随机数
int input = 0;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");//为0判断为假,跳出do while 循环
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
game.h
#pragma once
#include<stdio.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);
game.c
/初始化棋盘
void InitBoard(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++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
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");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("+");
}
}
}
printf("\n");
}
}
int x = 0;
int y = 0;
void PlayerMove(char board[ROW][COL], int row, int col)
{
printf("玩家走:>");
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("坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑走:>\n");
while (1)
{
x = rand() % row;//随机返回0-2
y = rand() % col;//随机返回0-2
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
注意:(1)x与y的随机值创建要放在while(1);之内
(2)在test.c的do while();外,创建了srand((unsigned int)time(NULL));之后,才能产生随机值
(6)判断游戏现在的状态(很重要,以下为完整代码)
test.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 board[ROW][COL];
//初始化棋盘 - 初始化空格
InitBoard(board, ROW , COL);
//打印一下棋盘 - 本质是打印数组的内容
DisplayBoard(board, ROW, COL);
char ret = 0;//接受游戏状态
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");
}
DisplayBoard(board, ROW, COL);
}
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");//为0判断为假,跳出do while 循环
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
game.h
#pragma once
#include<stdio.h>
#include<time.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 PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
//
//1.玩家赢了 - *
//2.电脑赢了 - #
//3.平局 - Q
//4.继续游戏 - c
//判断函数是否相等
char IsWin(char board[ROW][COL], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS
#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;
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");
if (i < row - 1)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("+");
}
printf("\n");
}
}
}
//
int x = 0;
int y = 0;
void PlayerMove(char board[ROW][COL], int row, int col)
{
printf("玩家走:>");
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("坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
//
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑走:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
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;
//判断3行
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];
}
}
//判断3列
for (i = 0; i < col; 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];
}
//判断平局
//如果棋盘盘满了,返回1,不满返回0
int ret = IsFull(board, row, col);
if (ret == 1)
{
return 'Q';
}
//继续
return 'c';
}
注意:(1)IsWin()的类型为char
(2)判断的实现
(3)test.c中为了让游戏持续进行要用while(1),而且需要下棋后打印棋盘.
(4)电脑与玩家每下一次,都要判断游戏状态
(5)判断游戏是否平局,为判断棋盘是否有'' ''
(6)判断时一定要加棋子不等于'' ''
好了!如果你认真看到这了,并且敲了代码的话,你一定学会了三子棋,快去和同学炫耀吧!
可以的话,点一下赞! 当然加上收藏就更好了