前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言实现三子棋

C语言实现三子棋

作者头像
对编程一片赤诚的小吴
发布2024-01-23 14:48:23
970
发布2024-01-23 14:48:23
举报

1.题目描述

  1. 三子棋,民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙等。
  2. 将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。

2.功能实现

想要用c语言完成,就得一步一步将所需实现的功能拆开,逐步实现(切记不可一步到位)。

1.开始界面

可以用一系列输出函数将开始界面进行输出,1为开始游戏,0为退出游戏,同时在主函数里进行调用,为了防止输入一次就结束运行,可用do while循环,先循环一次,再根据输入的是1还是0判断是否继续进行循环。

开始菜单函数。

代码语言:javascript
复制
void menu() {
	printf("***************************\n");
	printf("**********1.play**********\n");
	printf("**********0.exit***********\n");
	printf("***************************\n");
}

主函数

代码语言:javascript
复制
int main() {
	int input;
	srand((unsigned int)time(NULL));\\用于随机数的生成器,后面会有解释
	do {                            \\先进行一次循环,再根据input值进行判断是否继续
		menu();
		printf("请选择:\n");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;


		default:
			printf("选择错误,请重新选择\n");
			break;
		}



	} while (input);
		return 0;
}

有了开始菜单和输入功能,接下来就可以进行游戏功能实现了。

2.游戏功能

开始游戏功能实现前,我们需要明确它需要实现的功能有哪些。既然下棋,就得有棋盘吧,还得有旗子吧,最后还得有对手吧,这些我们来一一明确。

1.棋盘

可以知道的是,棋盘是一个3*3的矩阵方格,由纵线和横线划分成每一个方格。这里可以用一个二维数组来存放,在这里我们采用空格存放来达到初始化棋盘的目的,并在每一个数组的位置打印相应的线段来达到划分棋盘的效果,而棋盘的头部和尾部不需要进行划分线,所以在遍历时进行判断是否到达底部,否则打印。

代码语言:javascript
复制
void Initboard(char board[ROW][COL], int row,int col) {
	int i = 0;
	for (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) {
	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");//只打印前两行 
		}
		printf("\n");
	}

细心的老铁们可能已经看到,打印棋盘的代码只能满足3*3的棋盘,万一以后需要扩大玩法的话,效率并不是很高,所以我们直接进行对于所传入数组(行与列)进行遍历与判断,先打印数据,在打印分割行,这样就可以更加灵活与方便的进行棋盘的调整。

代码语言:javascript
复制
void Displayboard(char board[ROW][COL], int row, int col) {
	int i = 0;
	for (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 j = 0; j < col; j++) {
				printf("---");
				if (j < col - 1) printf("|");
			}

		}
		printf("\n");
	}
}
2.下棋

(玩家用*表示,电脑用#表示)这里很清楚的是,我们得通过输入棋盘相应的坐标来达到下棋的目标。其次还要对该坐标进行判断,如果上面已经有棋子了,那就得重新下。这里要注意,编译器与我们所输入的坐标不同的区别在于电脑下标从0开始,而我们输入的是1开始(不能保证玩的都是程序员)所以修改的坐标也有讲究。

这是玩家。

代码语言:javascript
复制
void PlayerMove(char board[ROW][COL], int row, int col) {
	int x, y;
	printf("玩家下棋\n");
	while (1) {
		printf("请输入要下棋的坐标:>");
		scanf_s("%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.如何生成随机数;2.控制生成坐标的范围;3.考虑该坐标上是否有棋子

1.针对随机数的情况,我们可以利用srand函数配合time函数(time函数的作用是生成一个时间戳,用于给srand提供可变参数,srand是随机数生成器)来生成随机数,利用rand函数生成相应坐标,为了控制范围,给生成数对行和列求余,同时进行判断相应坐标上是否有棋子

(ps:time函数和srand需要time.h和stalib.h头文件)

代码语言:javascript
复制
void ComputerMove(char board[ROW][COL], int row, int col) {
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while (1) {
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ') {
			board[x][y] = '#';
			break;
		}
	}

}
3.判断结果

对于结果来说,无非三种,输、赢、平局。

这里采用了对返回值进行判断来输出相应的结果(输出*,玩家赢,#则电脑赢,否则平局)。

赢的条件,任意棋子满足横竖或对角线即可,我们可以对数组所存放的值与位置进行判断,如果满足,返回对应棋子,如果都没有满足,则进行平局判断,通过对里面的空格数进行判断,如果都没有,则说明棋盘已满,且同时没有满足输赢条件,输出平局。

代码语言:javascript
复制
static int is_full(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 0;
		}
	}
	return 1;
}
//判断输赢或平局或游戏继续
char Iswin(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)) {
		return 'Q';
	}
	return 'C';
}

相关代码

1.测试代码

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"

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

void game() {
	char ret = 0;
	char board[ROW][COL];
	Initboard(board, ROW, COL);
	Displayboard(board, ROW, COL);
	//下棋
	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);
		//判断输赢
		if (ret != 'C') {
			break;
		}
	}
	if (ret == '*') {
		printf("玩家赢\n");
	}
	else if (ret == '#') {
		printf("电脑赢\n");
	}
	else {
		printf("平局\n");
	}


}




int main() {
	int input;
	srand((unsigned int)time(NULL));
	do {
		menu();
		printf("请选择:\n");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;


		default:
			printf("选择错误,请重新选择\n");
			break;
		}



	} while (input);
		return 0;
}

2.头文件代码

代码语言:javascript
复制
#pragma once
#define ROW 3
#define COL 3
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
//初始化棋盘
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);
//判断输赢
char Iswin(char board[ROW][COL], int row, int col);

编码相关小技巧

1.如果所需要的头文件过多,可以单独用一个头文件涵盖,在调用时就可以全部调用到,效率特高。

2.对于自定义函数功能的实现,也可以在自己的头文件里进行声明,也可大大提高效率。

3.如果编写的代码功能过多,可以一步一步来实现,切不可一步到位,从简到难更能加深思维的强化与理解。

(ps:新人博主,第一次写博客,还有些不熟悉,请多多指教(害羞))

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.题目描述
  • 2.功能实现
    • 1.开始界面
      • 2.游戏功能
        • 1.棋盘
        • 2.下棋
        • 3.判断结果
      • 相关代码
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档