带你玩转三子棋

Posted 七忆岁和

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带你玩转三子棋相关的知识,希望对你有一定的参考价值。

前言:所谓简易三子棋就是你和电脑下棋,当你和电脑其中有一方在棋盘中出现三行、三列或两条对角线有三个棋时,则那一方赢,接下来,就让我带你简单地操作一番。

1.设计主函数

int main()
{
	test();
	return 0;
}

我们所有的操作将会在test()函数中进行。

2.设计test函数

void test()
{
	int input = 0;
	int srand = ((unsigned)time(NULL));//初始化随机数
	do
	{
		menu();//最开始的菜单
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//选择1进入游戏(游戏函数)
			break;
		case 2:
			printf("退出游戏!\\n");
			break;
		default:
			printf("输入错误,请重新输入!");
			break;
		}
	} while (input);
}

3.打印菜单menu

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

4.进入游戏game

void game()
{
	char board[ROW][COL] = { 0 };
	Initboard(board, ROW, COL);//初始化棋盘
	Displayboard(board, ROW, COL);//打印棋盘
	int ret = 0;
    //下棋
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		Displayboard(board, ROW, COL);//每下一次就要打印棋盘

		ret = is_win(board, ROW, COL);//判断是不是赢了
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		computer_move(board, ROW, COL);
		Displayboard(board, ROW, COL);//每次电脑下棋也要记住并打印棋盘
		ret = is_win(board, ROW, COL);
        //结果判断
		// 玩家赢-‘*’
		// 电脑赢-‘#’
		// 继续-‘C’
		//平局(也就是棋盘满了的时候)-‘Q’
		if (ret != 'C')//判断结果是不是继续,不继续就代表出现了赢家
		{
			break;
		}
    }

接下来就让我们来进行棋盘的初始化、棋盘的打印、下棋操作以及结果的判断

1.棋盘的初始化

Initboard(board, ROW, COL)

首先,我们要知道三子棋的棋盘长什么样,才能实现

 

棋盘的初始化需要每个格子都是空的,直接使用二维数组的初始化就可以实现

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

2.棋盘的打印

Displayboard(board, ROW, COL)

三子棋的棋盘由虚线和实线分割组成,所以我们要想办法先把分割线打印出来

void Displayboard(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0, k = 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");
	}
}

3.玩家下棋

player_move(board, ROW, COL)

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0, y = 0;
	printf("玩家走:");
	while (1)
	{
		scanf("%d %d", &x, &y);//玩家输入的坐标比二维数组的下标要小1
		if (x >= 1 && x <= row && y >= 1 && y <= col)//判断玩家输入的坐标是否合法
		{
			if (board[x - 1][y - 1] == ' ')//判断玩家输入的坐标是否被占用
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该位置已被占用,请重新选择!");
			}
		}
		else
		{
			printf("输入错误!");
		}
	}
}

4.电脑下棋

computer_move(board, ROW, COL

void computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑走:\\n");
	int x = 0, y = 0;
	while (1)
	{
		x = rand() % ROW;//电脑输入的坐标由随机值产生
		y = rand() % COL;
		if (board[x - 1][y - 1] == ' ')//电脑随机下棋,只要棋盘中哪里有空格就可以下哪里
		{
			board[x - 1][y - 1] = '#';
			break;
		}
	}
}

5.结果判断

is_win(board, ROW, COL)

赢得游戏有三种情况:

a.一行中连续出现了三颗一样的棋

b.一列中连续出现了三颗一样的棋

c.对角线连续出现了三颗一样的棋(而对角线又可以分成撇对角线和捺对角线)

int is_win(char board[ROW][COL], int row, int col)
{
    //每行
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col-1; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j+2] && board[i][j]!=' ')
				return board[i][j];
		}
	}

    //每列
	i = 0; j = 0;
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < row - 1; i++)
		{
			if (board[i][j] == board[i+1][j] && board[i + 1][j] == board[i+2][j] && board[i][j] != ' ')
				return board[i][j];
		}
	}

    //捺对角线
	i = 0; j = 0;
	for (i = 0; i < row; i++)
	{
		if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i+2][j+2]&& board[i][i] != ' ')
			return board[i][i];
	}
    
    //撇对角线
	i = 0; j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = col-1; j >= 0; j--)
		{
			if (board[i][j] == board[i + 1][j - 1] && board[i + 1][j - 1] == board[i+2][j-2] && board[i][j] != ' ')
				return board[i][j];
		}
	}

	if (1 == is_full(board, ROW, COL))//判断棋盘是否满了
	{
		return 'Q';
	}
	else
		return 'C';
}

6.判断棋盘是否已满

int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')//有空格则没满,没满返回0
				return 0;
		}
	}
	return 1;//满了返回1
}

以上就是我们对三子棋的基本实现

后加餐:

头文件:

//sanziqi.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 5
#define COL 5
//初始化棋盘
void Initboard(char board[ROW][COL], int row, int col);
//打印棋盘
void Displayboard(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);

//结局判断
// 玩家赢-‘*’
// 电脑赢-‘#’
// 继续-‘C’
//平局(也就是棋盘满了的时候)-‘Q’

int is_win(char board[ROW][COL], int row, int col);

//判断棋盘是否满了
int is_full(char board[ROW][COL], int row, int col);

测试部分:

//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "sanziqi.h"

void game()
{
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	Initboard(board, ROW, COL);
	//打印棋盘
	Displayboard(board, ROW, COL);
	//下棋
	int ret = 0;
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		Displayboard(board, ROW, COL);

		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		computer_move(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}

		//结果判断
		// 玩家赢-‘*’
		// 电脑赢-‘#’
		// 继续-‘C’
		//平局(也就是棋盘满了的时候)-‘Q’
		
	}
	if (ret == '*')
	{
		printf("玩家赢!\\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢!\\n");
	}
	else
	{
		printf("平局!\\n");
	}
}

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

void test()
{
	int input = 0;
	int srand = ((unsigned)time(NULL));
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏!\\n");
			break;
		default:
			printf("输入错误,请重新输入!");
			break;
		}
	} while (input);
}

int main()
{
	test();
	return 0;
}

函数实现:

//sanziqi.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "sanziqi.h"
//初始化棋盘
void Initboard(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

//打印棋盘
void Displayboard(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0, k = 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 player_move(char board[ROW][COL], int row, int col)
{
	int x = 0, 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("该位置已被占用,请重新选择!");
			}
		}
		else
		{
			printf("输入错误!");
		}
	}
}

void computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑走:\\n");
	int x = 0, y = 0;
	while (1)
	{
		x = rand() % ROW;
		y = rand() % COL;
		if (board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '#';
			break;
		}
	}
}

int is_win(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col-1; j++)
		{
			//每行
			if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j+2] && board[i][j]!=' ')
				return board[i][j];
		}
	}

	i = 0; j = 0;
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < row - 1; i++)
		{
			//每列
			if (board[i][j] == board[i+1][j] && board[i + 1][j] == board[i+2][j] && board[i][j] != ' ')
				return board[i][j];
		}
	}

	i = 0; j = 0;
	for (i = 0; i < row; i++)
	{
		//对角线1
		if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i+2][j+2]&& board[i][i] != ' ')
			return board[i][i];
	}
	i = 0; j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = col-1; j >= 0; j--)
		{
			if (board[i][j] == board[i + 1][j - 1] && board[i + 1][j - 1] == board[i+2][j-2] && board[i][j] != ' ')
				return board[i][j];
		}
	}

	if (1 == is_full(board, ROW, COL))
	{
		return 'Q';
	}
	else
		return 'C';
}

int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

好了,简单的三子棋就到这了,你学废了吗?

以上是关于带你玩转三子棋的主要内容,如果未能解决你的问题,请参考以下文章

万字解析:带你走进五子棋(普通版)和三子棋的世界(C语言)

一篇文章带你玩转Mac Finder

手把手带你玩转Spark机器学习-使用Spark进行文本处理

带你玩转炫酷的CSS3

带你玩转Visual Studio——性能分析与优化

纯干货:21天带你玩转容器