C语言“三子棋”

本文介绍了如何用C语言编程实现一个简单的三子棋(井字棋)游戏。游戏包括初始化棋盘、玩家和电脑下棋、判断输赢等功能,并通过do-while循环和switch-case结构来控制游戏流程。代码包括游戏菜单、棋盘操作和游戏逻辑等部分。
摘要由CSDN通过智能技术生成

✌✌✌游戏介绍:

       相信很多人在儿时上学的时候都玩过三子棋,也就是平常大家说的井字棋。今天我带着大家用代码的方式把它实现出来。

       棋盘呈横三行列,纵三列分布,为九宫格样式。因为棋盘结构简单,所以在没有制式棋盘时,我们甚至可以随手拿笔画一个简易棋盘来进行游戏,而这最大的好处就是随便找个地方就可以玩这个简单而有趣的游戏了。

玩法:

        ☝☝☝在纸上我们一般都会画一个井字形的格子作为我们的游戏棋盘,两个玩家,一方用X表示棋子,一方使用O表示棋子,只要有一方的棋子可以连成一条线(横竖斜着连都判断获胜) 就算获胜,或者棋盘被画满,代表平局。

构思: 

1.实现游戏菜单

2.实现一个棋盘

3.初始化棋盘

4.打印棋盘

5.玩家下棋

6.电脑下棋

7.判断输赢


整体代码我们放在最下方:

                                 test.c  测试文件
                                 game.c  函数定义
                                 game.h  函数声明

游戏主体结构我们用do while循环,可以多一次循环让我们进入菜单栏,并进行选择。 

选择使用了swich case语句,选择1进入游戏函数主体,选择0退出,选择其他重新循环

void GameTest()
{
	int input = 0;
	do
	{
		meun();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误请重新选择\n");
			break;
		}
	} while (input);
}

int main()
{
	srand((size_t)time(NULL));
	GameTest();
	return 0;
}

1.游戏菜单

在选择前我们首先会打印一个菜单,让我们来看一下菜单函数

void meun()
{
	printf("******************************\n");
	printf("*****   1.play  0.exit   *****\n");
	printf("******************************\n");
}

选择的三种情况的不同结果:

当我们选择1后就会进入游戏主体,让我们继续往下走,看代码。

这就是我们整个游戏的框架,具体细节我们下方分解

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");
		}
		if(ret == 'Q')
		{
			printf("平局\n");
		}
}

 2.实现一个棋盘

井字可以可以把它看做一个3行3列的棋盘,所以我们使用二维数组创建

char board[ROW][COL];

3.初始化棋盘函数

初始化棋盘其实很简单,就是遍历二维数组,并且每个都制成空格符号

Initboard(char(*board)[COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

4.打印棋盘

打印的时候我们需要注意一下,要控制好格式,否则特别容易错位

void Displayboard(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			
			printf(" %c ", board[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		
		}
		printf("\n");
		if (i < row - 1)
		{
			for (int i = 0; i < row; i++)
			{
				printf("---");
				if (i < row - 1)
					printf("|");
			}
			printf("\n");
		}
	}
	printf("\n");
}

5.玩家下棋

玩家下棋,其实就是我们输入一个坐标位置,放入 * 号 ,当然我们需要进行一下判断,坐标是否合法,当前坐标有没有被放过棋子

还有一个需要注意的点是,我普通玩家会把第一行第一列的坐标当做1.1,但是在二维数组中他是0.0,所以我们要计算一下

void playermove(char board[ROW][COL], int row, int col)
{
	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("该坐标被占用\n");
				}
			}
			else
			{
				printf("坐标输入非法\n");
			}
		}
}

6.电脑下棋

电脑下棋就比较简单了,直接用rand函数生成随机坐标放入就可以,当然也要去判断一下是否合法

void computermove(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;
		}
	}
}

7.判断输赢

每次下棋的时候会出现4中情况:

1.玩家赢 返回 '*'

2.电脑赢 返回 '# ' 

3.棋盘满了 返回 'Q '

4.游戏继续 返回 'C' 

bool isfull(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return false;
			}
			
		}
	}
	return true;
}
char iswin(char board[ROW][COL], int row, int col)
{
	if (isfull(board,row,col))
	{
		return 'Q';
	}
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][2] !=' ')
		{
			return board[i][0];
		}
	}
	for (int j = 0; j < col ;j++)
	{
		if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[2][j] != ' ')
		{
			return board[j][0];
		}
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2]&& board[2][2] != ' ')
	{
		return board[0][0];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&& board[2][0] != ' ')
	{
		return board[0][2];
	}
	return 'C';
}

游戏测试截图 

 

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

void meun()
{
	printf("******************************\n");
	printf("*****   1.play  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");
		}
		if(ret == 'Q')
		{
			printf("平局\n");
		}
}

void GameTest()
{
	int input = 0;
	do
	{
		meun();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误请重新选择\n");
			break;
		}
	} while (input);
}

int main()
{
	srand((size_t)time(NULL));
	GameTest();
	return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

Initboard(char(*board)[COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void Displayboard(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			
			printf(" %c ", board[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		
		}
		printf("\n");
		if (i < row - 1)
		{
			for (int i = 0; i < row; i++)
			{
				printf("---");
				if (i < row - 1)
					printf("|");
			}
			printf("\n");
		}
	}
	printf("\n");
}

void playermove(char board[ROW][COL], int row, int col)
{
	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("该坐标被占用\n");
				}
			}
			else
			{
				printf("坐标输入非法\n");
			}
		}
}

void computermove(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;
		}
	}
}

bool isfull(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return false;
			}
			
		}
	}
	return true;
}
char iswin(char board[ROW][COL], int row, int col)
{
	if (isfull(board,row,col))
	{
		return 'Q';
	}
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][2] !=' ')
		{
			return board[i][0];
		}
	}
	for (int j = 0; j < col ;j++)
	{
		if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[2][j] != ' ')
		{
			return board[j][0];
		}
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2]&& board[2][2] != ' ')
	{
		return board[0][0];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&& board[2][0] != ' ')
	{
		return board[0][2];
	}
	return 'C';
}

game.h

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <stdbool.h>
#define ROW 3
#define COL 3

Initboard(char(*board)[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);

 上就是全部代码,还有很多需要优化的地方,我之后也会继续改良,如有错误和不足的地方。欢迎大家指正,完结撒花

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值