C语言·三子棋(具体步骤和代码)
作者:互联网
目录
前言
利用函数,分支和循环语句,数组,多文件实现。
棋盘:使用3行3列的二维数组以(" ")来表示;
玩家:利用填写行列实现以(" * ")下棋;
电脑:利用时间挫产生随机值实现以(" # ")下棋;
一、文件分配
game.c 用于游戏的实现
text.c 用于游戏的检测
game.h 用于游戏的函数引用,库函数的引用(将库函数的引用都放于头文件之中,这样可以使得代码不至于过于臃肿)
(介于game.h是作为引用,主要实现游戏以及检测游戏。text.c是用于游戏的检测;所以,必要时才展示)
二、菜单界面
使用do while循环的原因:
- 提高简洁性,我们所需要的,只是当不玩时即退出,输入错误即重新输入,而利用非0即对,0即错的性质,可简洁实现。
//游戏目录
void text()
{
int input = 0;
do
{
mune();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
//执行入口
int main()
{
text();
return 0;
}
//游戏首页
void mune()
{
printf("************************************\n");
printf("********** 1 play **********\n");
printf("************************************\n");
printf("********** 0 exit **********\n");
printf("************************************\n");
}
三、棋盘初始化
//初始化棋盘
char board[ROW][COL] = { 0 };
int i = 0, j = 0;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
四、打印棋盘
使用define定义常量的原因:
- 提高扩展性,如果将来要修改棋盘尺寸,代码修改会很方便,只需修改此一处。
#define ROW 3 //行
#define COL 3 //列
最直接的方法,可以实现,但是不够好。
//打印棋盘
void dis_printf(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//打印数据
printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//打印分割的行
if(i<row-1)
printf("---|---|---\n");
}
}
使用逐一打印的原因:
- 提高扩展性,当更改define定义常量后,正确的打印出棋盘。
- 提高实用性,使其不仅仅只能适用于三子棋,代码就要越完美越好,可实现多条件下的执行,不是仅仅满足当前。
//打印棋盘
void dis_printf(char board[ROW][COL],int row,int col)
{
int j = 0;
int i = 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");
}
}
}
样子
五、玩家落子
注意:玩家不是程序员,我们不能要求别人会C语言的数组,玩家只会以1起数而不是0,所以我们需要对,行列皆减1。
//玩家下棋(*)
void play_game(char board[ROW][COL],int row,int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请下棋->");
scanf("%d %d", &x, &y);
x--;
y--;
if (x >= 0 && x <= row && y >= 0 && y <= col)
{
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
else
{
printf("已经有棋,请重新下载\n");
}
}
else
{
printf("输入错误请重新输入\n");
}
}
}
下棋
六、电脑下棋
需注意:我们的棋盘是由限制的,所以随机生成的数值需要利用 " %行列 "以规定范围。
//电脑下棋(#)
void computer_printf(char board[ROW][COL],int row, int col)
{
int x = 0;
int y = 0;
srand((unsigned int)time(NULL));
while(1)
{
x = rand() % row;//0~2
y = rand() % col;//0~2
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
七、判断胜负
此处约定返回结果的含义:
(1)‘*’ 表示玩家获胜
(2)‘#’ 表示电脑获胜
(3)0表示胜负未分
(4) 1 表示和棋
此处的小聪明:我们让玩家赢与电脑赢都是返回其棋子的样子,这是便于返回,可以显得代码不会过于臃肿。
//判断结果
//如果,继续就返回0,平局就返回1,如果电脑赢就返回#,如果玩家赢就返回*.
int end_game(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][1] != ' ')
{
return board[i][1];
}
}
//判断列
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];
}
//判断是否继续或平局
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')//判断是否棋局是否还有空格
return 0;
}
}
return 1;
}
八、核心代码
我们知道,下棋是玩家与电脑回合制,不达到一家赢或平局,是不会停止的,所以我们需要创建几个一直正确的循环,然后,利用break语句跳出循环!
所以就有了以下的代码组合。
void game()
{
//初始化棋盘
char board[ROW][COL] = { 0 };
int i = 0, j = 0;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
//打印棋盘
dis_printf(board, ROW, COL);
int ret = 0;
while (1)
{
//玩家下棋
printf("玩家下棋\n");
play_game(board, ROW, COL);
//判断结果
ret = end_game(board, ROW, COL);
if (ret != 0)
{
break;
}
//打印棋盘
dis_printf(board, ROW, COL);
//电脑下棋
printf("电脑下棋\n");
computer_printf(board, ROW, COL);
//判断结果
ret = end_game(board, ROW, COL);
if (ret != 0)
{
break;
}
//打印棋盘
dis_printf(board, ROW, COL);
}
ret = end_game(board, ROW, COL);
if (ret == '*')
{
printf("玩家赢\n");
}
if (ret == '#')
{
printf("电脑赢\n");
}
if (ret == 1)
{
printf("平局\n");
}
}
只需要在玩家与电脑后放上一个if语句,判断只要不是继续游戏,就跳出循环,然后,在循环外判断谁赢,是否平局,这样只需要写这一次判断的代码,这样可以避免代码的臃肿。
总代码
game.h
#pragma once
//用于游戏的函数引用,头文件的说明
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3 //行
#define COL 3 //列
//首页
void mune();
//游戏
void game();
//打印棋盘
void dis_printf(char board[ROW][COL],int row,int col);
//玩家下棋
void play_game(char board[ROW][COL], int row, int col);
//电脑下棋
void computer_printf(char board[ROW][COL], int row, int col);
//判断结果
int end_game(char board[ROW][COL], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//用于游戏的实现
//游戏首页
void mune()
{
printf("************************************\n");
printf("********** 1 play **********\n");
printf("************************************\n");
printf("********** 0 exit **********\n");
printf("************************************\n");
}
//打印棋盘
void dis_printf(char board[ROW][COL],int row,int col)
{
int j = 0;
int i = 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 play_game(char board[ROW][COL],int row,int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请下棋->");
scanf("%d %d", &x, &y);
x--;
y--;
if (x >= 0 && x <= row && y >= 0 && y <= col)
{
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
else
{
printf("已经有棋,请重新下载\n");
}
}
else
{
printf("输入错误请重新输入\n");
}
}
}
//电脑下棋(#)
void computer_printf(char board[ROW][COL],int row, int col)
{
int x = 0;
int y = 0;
srand((unsigned int)time(NULL));
while(1)
{
x = rand() % row;//0~2
y = rand() % col;//0~2
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//判断结果
//如果,继续就返回0,平局就返回1,如果电脑赢就返回#,如果玩家赢就返回*.
int end_game(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][1] != ' ')
{
return board[i][1];
}
}
//判断列
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];
}
//判断是否继续或平局
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')//判断是否棋局是否还有空格
return 0;
}
}
return 1;
}
text.c
#define _CRT_SECURE_NO_WARNINGS 1
//用于游戏的检测
#include "game.h"
void game()
{
//初始化棋盘
char board[ROW][COL] = { 0 };
int i = 0, j = 0;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
//打印棋盘
dis_printf(board, ROW, COL);
int ret = 0;
while (1)
{
//玩家下棋
printf("玩家下棋\n");
play_game(board, ROW, COL);
//判断结果
ret = end_game(board, ROW, COL);
if (ret != 0)
{
break;
}
//打印棋盘
dis_printf(board, ROW, COL);
//电脑下棋
printf("电脑下棋\n");
computer_printf(board, ROW, COL);
//判断结果
ret = end_game(board, ROW, COL);
if (ret != 0)
{
break;
}
//打印棋盘
dis_printf(board, ROW, COL);
}
ret = end_game(board, ROW, COL);
if (ret == '*')
{
printf("玩家赢\n");
}
if (ret == '#')
{
printf("电脑赢\n");
}
if (ret == 1)
{
printf("平局\n");
}
}
void text()
{
int input = 0;
do
{
mune();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
int main()
{
text();
return 0;
}
游戏的结果
(可惜就是因为电脑随机下,就显得电脑特别特别笨……,所以电脑赢难,平局更难……)
玩家赢
电脑赢
平局
标签:int,三子,C语言,game,board,printf,ROW,COL,具体步骤 来源: https://blog.csdn.net/weixin_64609308/article/details/122474156