【C++ 程序】 井字棋游戏(人 VS Lv1电脑)

这是 Lv1 电脑级别,其中的逻辑是剩余的空位随机选择下在哪里。

程序

//This program is a simple tic-tac-toe game.

#include <iostream>
#include <string>
#include <cstddef>
#include <stdexcept>
#include <ctime>
using namespace std;

char point_now[3][3] = {
    
     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
char player = 'X';
char computer_player = 'X';
unsigned step_count = 0;

int win_lose(char point[3][3], int n)
{
    
    
	if (point[0][0] == point[0][1] && point[0][1] == point[0][2] && point[0][0] == 'X') return 1; // X wins
	if (point[1][0] == point[1][1] && point[1][1] == point[1][2] && point[1][0] == 'X') return 1; // X wins
	if (point[2][0] == point[2][1] && point[2][1] == point[2][2] && point[2][0] == 'X') return 1; // X wins
	if (point[0][0] == point[1][0] && point[1][0] == point[2][0] && point[0][0] == 'X') return 1; // X wins
	if (point[0][1] == point[1][1] && point[1][1] == point[2][1] && point[0][1] == 'X') return 1; // X wins
	if (point[0][2] == point[1][2] && point[1][2] == point[2][2] && point[0][2] == 'X') return 1; // X wins
	if (point[0][0] == point[1][1] && point[1][1] == point[2][2] && point[1][1] == 'X') return 1; // X wins
	if (point[0][2] == point[1][1] && point[1][1] == point[2][0] && point[1][1] == 'X') return 1; // X wins

	if (point[0][0] == point[0][1] && point[0][1] == point[0][2] && point[0][0] == '0') return 2; // 0 wins
	if (point[1][0] == point[1][1] && point[1][1] == point[1][2] && point[1][0] == '0') return 2; // 0 wins
	if (point[2][0] == point[2][1] && point[2][1] == point[2][2] && point[2][0] == '0') return 2; // 0 wins
	if (point[0][0] == point[1][0] && point[1][0] == point[2][0] && point[0][0] == '0') return 2; // 0 wins
	if (point[0][1] == point[1][1] && point[1][1] == point[2][1] && point[0][1] == '0') return 2; // 0 wins
	if (point[0][2] == point[1][2] && point[1][2] == point[2][2] && point[0][2] == '0') return 2; // 0 wins
	if (point[0][0] == point[1][1] && point[1][1] == point[2][2] && point[1][1] == '0') return 2; // 0 wins
	if (point[0][2] == point[1][1] && point[1][1] == point[2][0] && point[1][1] == '0') return 2; // 0 wins

	if (n == 9) return 3; // end up in a draw
	else return 0; // unfinished
}

void game_player_change(char& player)
{
    
    
	if (player == 'X')
		player = '0'; // X -> 0
	else player = 'X';// 0 -> X
}

string computer1(char p[3][3])
{
    
    
	string ret;
	const string location_computer[3][3] = {
    
     {
    
    "A1","A2","A3"},{
    
    "B1","B2","B3"},{
    
    "C1","C2","C3"} };
	unsigned available_n = 49;
	for (int c_i = 0; c_i != 3; c_i++)
	{
    
    
		for (int c_j = 0; c_j != 3; c_j++)
		{
    
    
			if ((p[c_i][c_j] != 'X') && (p[c_i][c_j] != '0'))
				p[c_i][c_j] = available_n++; // mark empty places with numbers 1,2,3...
		}
	}
	srand((unsigned)time(NULL));
	int ran = rand() % (available_n - 49) + 49; // generate a random number
	for (int c_i = 0; c_i != 3; c_i++)
	{
    
    
		for (int c_j = 0; c_j != 3; c_j++)
		{
    
    
			if (p[c_i][c_j] == ran)
				ret = location_computer[c_i][c_j]; // the chosen place
		}
	}
	for (int c_i = 0; c_i != 3; c_i++)
	{
    
    
		for (int c_j = 0; c_j != 3; c_j++)
		{
    
    
			if ((p[c_i][c_j] != 'X') && (p[c_i][c_j] != '0'))
				p[c_i][c_j] = ' '; // return to Space
		}
	}
	return ret; // this is the copmuter-chosen location
}

int main()
{
    
    
	std::cout << "This program is a simple tic-tac-toe game.\nProgrammer:Teddy van Jerry\n" << endl;
	std::cout << "Difficulty :Level 1.0\n" << endl;
	std::cout << "You go first or the computer? You(1), Computer(2): ";
	char You_or_Computer;
	cin >> You_or_Computer;
	cout << endl;
	if (You_or_Computer == '1')
		computer_player = '0';
	else computer_player = 'X';

	// Print an empty board.
	std::cout << "| |1|2|3|" << endl;
	std::cout << "|A| | | |" << endl;
	std::cout << "|B| | | |" << endl;
	std::cout << "|C| | | |\n" << endl;

	while (win_lose(point_now, step_count) == 0)
	{
    
    
		string location;
		unsigned location_letter = 0; // A/B/C
		unsigned location_number = 0; // 1/2/3

	begin: // a label

		std::cout << "Player " << player << ", make your move: ";
		if (player != computer_player)
			cin >> location; // input the location (e.g. B2)
		else
		{
    
    
			location = computer1(point_now);
			cout << location << endl;
		}
		std::cout << endl;

		switch (location[0])
		{
    
    
		case 'a': case 'A':
			location_letter = 0;
			break;
		case 'b': case 'B':
			location_letter = 1;
			break;
		case 'c': case 'C':
			location_letter = 2;
			break;
		default: // illegal input
			location_letter = 100; // indicate an error
			break;
		}

		switch (location[1])
		{
    
    
		case '1':
			location_number = 0;
			break;
		case '2':
			location_number = 1;
			break;
		case '3':
			location_number = 2;
			break;
		default: // illegal input
			location_number = 100; // indicate an error
			break;
		}

		try
		{
    
    
			if (location_letter != 100 && location_number != 100 && point_now[location_letter][location_number] == ' ')
				point_now[location_letter][location_number] = player;
			else throw runtime_error("Illegal input!");
		}
		catch (runtime_error err)
		{
    
    
			std::cout << err.what() << "\nTry Again? Enter Y or N." << endl;
			char decision;
			cin >> decision;
			if (!cin || decision == 'n' || decision == 'N')
				break;
			else
			{
    
    
				cout << endl;
				goto begin; // go back to the label 'begin'
			}
		}

		// Print the board
		std::cout << "| |1|2|3|" << endl;
		std::cout << "|A|" << point_now[0][0] << "|" << point_now[0][1] << "|" << point_now[0][2] << "|" << endl;
		std::cout << "|B|" << point_now[1][0] << "|" << point_now[1][1] << "|" << point_now[1][2] << "|" << endl;
		std::cout << "|C|" << point_now[2][0] << "|" << point_now[2][1] << "|" << point_now[2][2] << "|" << endl;

		game_player_change(player); // change the player
		++step_count; // count one more time
		std::cout << endl;
	}

	int final_result = win_lose(point_now, step_count);
	char winner='N';
	switch (final_result)
	{
    
    
	case 1:
		winner = 'X';
		std::cout << "Congratulations! The winner is X." << endl;
		break;
	case 2:
		winner = '0';
		std::cout << "Congratulations! The winner is 0." << endl;
		break;
	case 3:
		std::cout << "The game ended in a draw." << endl;
		break;
	}
	if (winner == computer_player)
		cout << "Computer won!" << endl;
	else
	{
    
    
		if (winner != 'N')
			cout << "You won!!!" << endl;
	}

	std::cout << "\nALL RIGHTS RESERVED (c) 2020 Teddy van Jerry" << endl;
	return 0;
}

//Copyright :2020 Teddy van Jerry

输出示例

Output
真够笨的,哈哈!!!这么轻松就赢了。

分析

  • 本来用的 uniform_int_distribution<unsigned> u<m,n>;时而可以,时而报错。而且随机数每次一样,于是就做出了修改。
  • 该程序一样对于不合法输入进行了判别(分为两种:1.坐标超出范围,2.输入到原来已有棋子的位置上),详见【C++ 程序】 井字棋游戏(人 VS 人)中的分析。
  • 格外应注意69-76行的内容非常必要,对于全局变量的影响不会随着该函数结束而结束。详见我的博客 关于 C++中 定义函数造成影响 的思考

ALL RIGHTS RESERVED © 2020 Teddy van Jerry
欢迎转载,转载请注明出处。


See also

Teddy van Jerry 的导航页
【C++ 程序】 井字棋游戏(人 VS 人)
【C++ 程序】 井字棋游戏(人 VS Lv2电脑)
【C++ 程序】 井字棋游戏(人 VS Lv3电脑)
【C++ 程序】 井字棋游戏(人 VS Lv3电脑)(战绩统计版)
【C++ 程序】 五子棋游戏(人 VS 人)
【C++ 程序】 随机数
【C++ 程序】 移动迷宫游戏
【C++ 程序】 贪吃蛇游戏
【C++ 程序】 数字推盘游戏(15-puzzle)
【C++ 程序】 2048游戏
【C++ 程序】 井字棋游戏(人 VS 人)(EasyX 图形界面)
【C++ 程序】 井字棋游戏(人 VS Lv3电脑)(战绩统计版)(EasyX 图形界面)

猜你喜欢

转载自blog.csdn.net/weixin_50012998/article/details/108331456