目录
目录
一、基本问题
如何用C语言实现简单的三子棋小游戏
二、基本实现逻辑
1、出现是选择玩游戏的界面
2、出现棋盘并且初始化棋盘
3、通过坐标实现下棋
4、玩家落子之后,实现电脑落子
5、通过函数返回的字符判断输赢
6、执行第二部继续玩游戏
三、实现步骤
1、首先实现环境配置,使用game.h头文件实现函数声明,game.c实现游戏函数,test.c实现游戏的测试
2、main函数在test.c文件中,游戏实现的函数在test.c中被引用,而函数的实现主要是在game.c文件中完成。game.h文件中包含了程序所需的各种头文件并且包换对实现游戏功能的各种函数的声明。
3、代码实现打印菜单,游戏至少运行一次,所以在main函数使用do{}while()循环,打印菜单
菜单代码
void menu() {
printf("**********************\n");
printf("****1.play 0.exit****\n");
printf("**********************\n");
}
通过main函数打印出菜单,switch语句判断输入值为1或0来开始或退出游戏
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");
break;
}
} while (input);
}
当我们选择1时,调用game()函数来实现游戏,想要玩游戏,那我们就得用二维数组char[ROW][COL]来创建一个棋盘,并且让棋盘初始化,实现玩家下棋的函数和电脑下棋的函数,判断游戏的输赢,现在在头文件中声明这些我们要实现的函数。
#pragma once
#include<stdio.h>
#define ROW 3
#define COL 3
#include<time.h>
#include<stdlib.h>
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);
//打印棋盘
void display_board(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);
在game.c中来实现打印棋盘的函数,在函数中通过循环来实现棋盘布局的打印。用行和列来限制棋盘的打印
void display_board(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");
}
}
}
为了使棋盘更美观,整洁,我们在game.c利用二维数组将棋盘每个格子赋值为空格。
void init_board(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] = ' ';
}
}
}
接下来就得在game.c中实现玩家下棋的函数,因为只是简单涉及c语言,我们用坐标来代替鼠标输入玩家要下的棋‘*’,x为横坐标,y为纵坐标,并且判断坐标是否被占用,以及坐标是否超出我们棋盘的格子。
//玩家下棋实现函数
void player_move(char board[ROW][COL], int row, int col) {
//设定x,y为坐标的输入值
int x = 0, y = 0;
printf("玩家下棋:>\n");
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");
}
}
}
接下来实现电脑在棋盘上的落子,电脑落子必须是变化的,不能让电脑只在一个坐标上落子,在我们生活中,时间是不断发生变化的,所以我们用时间戳来实现电脑落子的随机性。在主函数中使用srand()来接受时间戳传递给rand(),让rand()函数产生随机值,因为rand()产生的值是0~32672,s所以%row,%col使x和y接收的值在0~2之间,并且判断落子处是否为空格,使电脑的落子‘#’能够落在棋盘上。使用rand()和srand(),time需要在game.h中包含#include<stdlib.h>和#include<time.h>这两个库函数。
void computer_move(char board[ROW][COL], int row, int col) {
printf("电脑下棋\n");
while (1) {
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ') {
board[x][y] = '#';
break;
}
}
}
在game.c中判断游戏状态
创建一个is_win()函数并根据最终棋盘上的结果返回一个字符打印最后的结果
返回的符号代表的意义:
玩家赢:*
电脑萤:#
平局:Q
继续:C
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][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 (is_full(board,row,col) == 1) {
return 'Q';
}
//继续游戏
return 'C';
}
在game.c中创建is_full()函数来判断格子是否被占满,如果满了返回1,反之则0,在is_win函数中用if判断is_full()返回的值来判断游戏继续还是平局。
int is_full(char board[ROW][COL], int row, int col) {
//此函数判断棋盘有没有被填满,填满了返回1,没填满返回0。
int i = 0;
for (i = 0; i < row; i++) {
int j = 0;
for (j = 0; j < col; j++) {
if (' ' == board[i][j]) {
return 0;
}
}
}
return 1;
}
在test.c中用game()来实现函数的组合调用,将is_win()返回的值用ret接受来并在每次打印后判断判断游戏的状态。为了避免重复打印棋盘,我们在game()中加入system("cls")来清楚屏幕,使得屏幕中只出现一张棋盘。
void game() {
char ret = 0;
char board[ROW][COL] = {0};
init_board(board, ROW, COL);
display_board(board, ROW, COL);
//玩游戏
while (1) {
System("cls");
player_move(board, ROW, COL);
ret=is_win(board, ROW, COL);
if (ret != 'C')
break;
//玩家下棋打印棋盘
display_board(board, ROW, COL);
computer_move(board, ROW, COL);;
//电脑下棋之后打印棋盘
display_board(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*') {
printf("玩家赢\n");
}
else if (ret == '#') {
printf("电脑赢\n");
}
else if(ret == 'Q')
printf("平局了\n");
}
整合代码
game.h
#pragma once
#include<stdio.h>
#define ROW 3
#define COL 3
#include<time.h>
#include<stdlib.h>
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);
//打印棋盘
void display_board(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);
game.c
#include"game.h"
//初始化棋盘
void init_board(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 display_board(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");
}
}
}
//玩家下棋实现函数
void player_move(char board[ROW][COL], int row, int col) {
//设定x,y为坐标的输入值
int x = 0, y = 0;
printf("玩家下棋:>\n");
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 computer_move(char board[ROW][COL], int row, int col) {
printf("电脑下棋\n");
while (1) {
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ') {
board[x][y] = '#';
break;
}
}
}
//判断游戏状态
int is_full(char board[ROW][COL], int row, int col) {
//此函数判断棋盘有没有被填满,填满了返回1,没填满返回0。
int i = 0;
for (i = 0; i < row; i++) {
int j = 0;
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][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 (is_full(board,row,col) == 1) {
return 'Q';
}
//继续游戏
return 'C';
}
test.c
#include"game.h"
//三子棋游戏
void menu() {
printf("**********************\n");
printf("****1.play 0.exit****\n");
printf("**********************\n");
}
void game() {
char ret = 0;
char board[ROW][COL] = {0};
init_board(board, ROW, COL);
display_board(board, ROW, COL);
//玩游戏
while (1) {
system("cls")
player_move(board, ROW, COL);
ret=is_win(board, ROW, COL);
if (ret != 'C')
break;
//玩家下棋打印棋盘
display_board(board, ROW, COL);
computer_move(board, ROW, COL);;
//电脑下棋之后打印棋盘
display_board(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*') {
printf("玩家赢\n");
}
else if (ret == '#') {
printf("电脑赢\n");
}
else if(ret == 'Q')
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");
break;
}
} while (input);
}
祝每个参考的小伙伴都能轻松实现哦,再见咯。