(C语言篇)三子棋的实现
Posted 向阳a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(C语言篇)三子棋的实现相关的知识,希望对你有一定的参考价值。
前言:不知不觉已经学习C语言一个月了,收获了很多知识,特别是学会了编写三子棋小游戏令我很是兴奋,今天我们就来认识认识它,话不多说,我们正式开始。
文章目录
一. 三子棋
本次编写的三子棋分为三个文件,他们再同一工程下,分别为test.c、game.h、game.c,test.c文件主要用于实现进入游戏、退出游戏、判断输赢、打印菜单等逻辑,而game.c则用于编写游戏的主要实现方法,game.h则存放头文件和函数的声明。
三子棋具体的实现如图。
二. 进入或退出游戏的逻辑
1. test.c文件
#include "game.h"
void menu() {
printf("----------------------------------\\n");
printf("----------- 1.play -----------\\n");
printf("----------- 0.exit -----------\\n");
printf("----------------------------------\\n");
}
void test() {
int input = 0;
do {
menu(); //菜单
printf("请选择输入1/0: "); //选择继续游戏或退出
scanf("%d", &input);
switch (input) {
case 1: //为1则进入游戏
printf("三子棋\\n");
break;
case 0 :
printf("退出游戏\\n");
break;
default:
printf("你输入的数字不在范围内,请重新输入\\n");
break;
}
printf("\\n");
} while (input); //input为1则继续,为0退出游戏,其他则重新输入
}
int main() {
test();
return 0;
}
这里可以把需要引用的头文件放入game.h,这样当game.c和test.c源文件需要引用相同的头文件时只需引用game.h文件即可,这样做会方便很多。如两个源文件都需引用#include <stdio.h>这时只需放入game.h中引用game.h文件。接下来我们来看看以上运行结果:
当代码运行无问题时,我就可以把printf(“三子棋”);换为game函数了。
三. 初始化棋盘
1. test.c文件(后面不再展示全部,只展示game函数的内容)
#include "game.h"
void menu() {
printf("----------------------------------\\n");
printf("----------- 1.play -----------\\n");
printf("----------- 0.exit -----------\\n");
printf("----------------------------------\\n");
}
void game() {
char board[ROW][COL] = { 0 }; //想打印棋盘需要一个二维数组初始化为0
Init(board, ROW, COL); //初始化棋盘,即把棋盘都初始化为空格。
}
void test() {
int input = 0;
do {
menu(); //选择菜单
printf("请选择输入1/0: "); //选择继续游戏或退出
scanf("%d", &input);
switch (input) {
case 1: //为1则进入游戏
game();
break;
case 0 :
printf("退出游戏\\n");
break;
default:
printf("你输入的数字不在范围内,请重新输入\\n");
break;
}
printf("\\n");
} while (input); //input为1则继续,为0退出游戏,其他则重新输入
}
int main() {
test();
return 0;
}
2. game.h文件(后面还需声明函数时不再展示)
#include <stdio.h>
#define ROW 3 //行
#define COL 3 //列
void Init(char board[ROW][COL], int row, int col);//初始化棋盘
3. game.c文件
#include "game.h"
void Init(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] = ' ';
}
}
}
这里定义#define ROW 3 和 #define COL 3 是为了方便我们改进代码,如当我们想打印五子棋棋盘时就把 3 改为 5。
四. 打印棋盘
1. test.c文件
void game() {
char board[ROW][COL] = { 0 }; //想打印棋盘需要一个二维数组初始化为0
Init(board, ROW, COL); //初始化棋盘,即把棋盘都初始化为空格。
//打印棋盘
PrintBoard(board, ROW, COL);
}
2. game.c文件
//打印棋盘
void PrintBoard(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]);
if (j < col - 1) {
printf("|"); //最后一列后不需要打印|
}
}
printf("\\n"); //打印完需换行
if (i < col - 1) { //最后一行下不用打印___
for (j = 0; j < col; j++) {
printf("___");
if (j < col - 1) {
printf("|");
}
}
}
printf("\\n");//打印完需换行
}
}
结果如图:
即:这里为一组数据
五. 玩家下棋
1.test.c文件
void game() {
char board[ROW][COL] = { 0 }; //想打印棋盘需要一个二维数组初始化为0
Init(board, ROW, COL); //初始化棋盘,即把棋盘都初始化为空格。
//打印棋盘
PrintBoard(board, ROW, COL);
//玩家和电脑下棋'*'代表玩家,'#'代表电脑。
while (1) {
player_move(board, ROW, COL);//玩家下棋
PrintBoard(board, ROW, COL);//下完后继续打印
}
}
2. game.c文件
//玩家下棋
void player_move(char board[ROW][COL], int row, int col) {
int x = 0; //行
int y = 0; //列
printf("玩家输入: ");
while (1) {
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");
break;
}
}
else {
printf("你输入的坐标无效,请重新输入\\n");
break;
}
}
}
用if (board[x - 1][y - 1] == ’ ')这条语句是为了防止这个坐标已经下过了。
这里的用x-1、y-1的原因是:
所以需要减1,其运行结果为:
六. 电脑下棋
1. test.c文件
void game() {
char board[ROW][COL] = { 0 }; //想打印棋盘需要一个二维数组初始化为0
Init(board, ROW, COL); //初始化棋盘,即把棋盘都初始化为空格。
//打印棋盘
PrintBoard(board, ROW, COL);
//玩家和电脑下棋'*'代表玩家,'#'代表电脑。
while (1) {
player_move(board, ROW, COL);//玩家下棋
PrintBoard(board, ROW, COL);//下完后继续打印
computer_move(board, ROW, COL);//电脑下棋
PrintBoard(board, ROW, COL);//下完继续打印
}
}
2. game.c文件
//电脑下棋
void computer_move(char board[ROW][COL], int row, int col) {
printf("电脑下棋: \\n");
while (1) { //利用循环直到电脑满足输入。
int x = rand() % row; //生成0~2的数
int y = rand() % col; //0~2
if (board[x][y] == ' ') {
board[x][y] = '#';
break;
}
}
}
这里电脑生成随机数,利用rand函数,在生成随机数时需要srand()函数辅助,在test.c文件中的test函数中加入srand((unsigned int)time(NULL));这条语句。
运行结果为:
七. 判断输赢
1. test.c文件
void game() {
char board[ROW][COL] = { 0 }; //想打印棋盘需要一个二维数组初始化为0
Init(board, ROW, COL); //初始化棋盘,即把棋盘都初始化为空格。
//打印棋盘
PrintBoard(board, ROW, COL);
//玩家和电脑下棋'*'代表玩家,'#'代表电脑。
/*
玩家赢则返回'*'
电脑赢则返回'#'
平局则返回'M'
返回字符C则没结束
*/
//判断输赢
char ret = 0;
while (1) {
//玩家下棋
player_move(board, ROW, COL);
PrintBoard(board, ROW, COL);//下完后继续打印
ret = is_win(board, ROW, COL);//每下完一次判断输赢一次。
if (ret != 'C') {
break; //不等于字符C说明结束
}
//电脑下棋
computer_move(board, ROW, COL);
PrintBoard(board, ROW, COL);//下完继续打印
ret = is_win(board, ROW, COL);//每下完一次判断输赢一次。
if (ret != 'C') {
break;
}
}
if (ret == '*') {
printf("玩家赢\\n");
}
else if (ret == '#') {
printf("电脑赢\\n");
}
else {
printf("平局");
}
}
2. game.c文件
//判断输赢
int is_full(char board[ROW][COL], int row, int col) {//判断棋盘有没有满,满了就平局返回1,没满返回0
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 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][1] != ' ') { //把空格排除
return board[i][0];//返回这个数,可能是*也可能是#。
}
}
//判断列数是否相连(共三列)
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];
}
//平局
if (is_full(board, row, col) == 1) {
return 'M';
}
return 'C';
}
值得注意的是这里玩家下一次就进入此is_win函数进行判断并返回一个字符,电脑下一次棋也判断一次,返回一个字符,直到分出输赢、平局。
运行结果:
玩家赢:
电脑赢:
平局:
完整代码
1. test.c
#include "game.h"
void menu() {
printf("----------------------------------\\n");
printf("----------- 1.play -----------\\n");
printf("----------- 0.exit -----------\\n");
printf("----------------------------------\\n")C语言从入门到入土(入门特别篇)三子棋小游戏及如何让朋友也能玩自己写的游戏(程序)(exe如何附带动态链接库dll)