井字棋人机

井字棋人机对弈的实现


    以3*3的二维数组存放棋盘,输入两个数字表示要下的位置,然后人机对弈;


1.划分模块

        (1). 输出模块

                        输出棋盘:不断的清屏、打印、清屏、打印以实现动画式的效果( 一般都会把清除光标带上的 )。
                        输出结果:谁输谁赢。

       (2).判断模块

                      此处分为两个模块
                         其一用来判断所选位置是否可以下(即是否已经存在棋子),
                         其二是判断当前棋面是否有输赢,或平局。

       (3).电脑下棋模块

                     此模块最为重要,要考虑到各种情况的应对措施,思路下面具体说;

       (4).主函数

                    把问题分小了,划分为各个模块,用子函数实现,主函数相对来说就简单了。

2.简单思路介绍

            输出棋盘的操作都带着清屏 打印 (cls、print);

            判断就返回两个值表示是否即可,这些都不是重点;

            重点是这里,人机博弈:首先有个优先度,

                    第一: 要赢;

                    第二:在实在不能赢的情况下,不能输,最多为平局;

                    第三:如果以上都没有,就随机下;

3.代码实现及详细思路

        就按源代码中的顺序写了,思路自己对应一下吧。


        1.去光标
        
//	去光标 
void qgb ( )	
{
	HANDLE handle = GetStdHandle ( STD_OUTPUT_HANDLE );  
	CONSOLE_CURSOR_INFO CursorInfo;  
	GetConsoleCursorInfo ( handle, &CursorInfo );
	CursorInfo.bVisible = false; 
	SetConsoleCursorInfo ( handle, &CursorInfo );
}

    2.判断所选位置是否可以下子
//	判断所选位置是否可下 不可下返回-1 可以下返回0 
int IsNULL ( int array[3][3], int x, int y )
{
	if ( array[x][y] == 0 ) return 0;
	return -1;
}
    3.打印棋盘
            不断的清屏 打印 清屏 打印;
//	打印棋盘 
void Print ( int array[3][3] )
{
	system( "cls" );
	int i, j;
	printf ( "\n\n\t井 字 棋\n" );
	for ( i = 0; i < 3; i ++ )
	{				  
		printf ( "\n\t+-+-+-+\n\t|" );
		for ( j = 0; j < 3; j ++ )
		{
			if ( array[i][j] == 0 ) printf( " " );
			if ( array[i][j] == 1 ) printf( "X" );
			if ( array[i][j] == -1 ) printf( "O" );
			printf( "|" );
		}
	}
	printf ( "\n\t+-+-+-+\n\n" );
}
    4.电脑下棋部分

        其一考虑赢,即有一线有两个自己的棋子,则优先放在第三个的位置。

        其二考虑不输,即不然对方赢,一条线上有两个对方棋子,则下在第三个位置堵住。

        其三随机下。

        重点:一定要按该思路的顺序 先考虑赢,再考虑不输,最后考虑随机,即使你分 横竖撇捺的位置来实现的,最后也得等赢的情况全部考虑完在考虑其他情况,我刚开始就傻逼了。

    代码:

//	电脑下子 
int GO ( int array[3][3] )
{
	int i, t;
	int k;
	for ( i = 0; i < 3; i ++ )
	{
		t = array[i][0] + array[i][1] + array[i][2];
		if ( t == -2 )
		{
			for ( k = 0; k < 3; k ++ )
			{
				if ( array[i][k] == 0 )
				{
					array[i][k] = -1;
					return 0;
				} 
				
			}
		} 
	}
	for ( i = 0; i < 3; i ++ )
	{
		t = array[0][i] + array[1][i] + array[2][i];
		if ( t == -2 )
		{
			for ( k = 0; k < 3; k ++ )
			{
				if ( array[k][i] == 0 )
				{
					array[k][i] = -1;
					return 0;
				}
			}
		} 
	}
	int j = 0; t = 0;
	for ( i = 0; i < 3; i ++ )
	{
		j += array[i][i];
		t += array[i][2-i];
	}
	if ( t == -2 )
	{
		for ( k = 0; k < 3; k ++ )
		{
			if ( array[k][2-k] == 0 )
			{
				array[k][2-k] = -1;
				return 0;
			} 
		}
	}
	if ( j == -2 )
	{
		for ( k = 0; k < 3; k ++ )
		{
			if ( array[k][k] == 0 ) 
			{
				array[k][k] = -1;
				return 0;
			}
		}
	}
	
	
	
	for ( i = 0; i < 3; i ++ )
	{
		t = array[i][0] + array[i][1] + array[i][2];
		if ( t == 2 )
		{
			for ( k = 0; k < 3; k ++ )
			{
				if ( array[i][k] == 0 )
				{
					array[i][k] = -1;
					return 0;
				} 
				
			}
		} 
	}
	for ( i = 0; i < 3; i ++ )
	{
		t = array[0][i] + array[1][i] + array[2][i];
		if ( t == 2 )
		{
			for ( k = 0; k < 3; k ++ )
			{
				if ( array[k][i] == 0 )
				{
					array[k][i] = -1;
					return 0;
				}
			}
		} 
	}
	j = 0; t = 0;
	for ( i = 0; i < 3; i ++ )
	{
		j += array[i][i];
		t += array[i][2-i];
	}
	if ( t == 2 )
	{
		for ( k = 0; k < 3; k ++ )
		{
			if ( array[k][2-k] == 0 )
			{
				array[k][2-k] = -1;
				return 0;
			} 
		}
	}
	if ( j == 2 )
	{
		for ( k = 0; k < 3; k ++ )
		{
			if ( array[k][k] == 0 ) 
			{
				array[k][k] = -1;
				return 0;
			}
		}
	}
	
	
	while ( 1 )
	{
		srand ( time ( 0 ) );
		i = rand ( ) % 3;
		j = rand ( ) % 3;
		if ( IsNULL ( array, i, j ) == 0 )
		{
			array[i][j] = -1;
			break;
		}
	}
	return 0;
}
    5.检查胜负情况

    代码:

//	平局返回0;正方胜返回1;负反胜利返回-1;否则返回6; 
int Check ( int array[3][3] )
{
	int i, t;
	for ( i = 0; i < 3; i ++ )
	{
		t = array[i][0] + array[i][1] + array[i][2];
		if ( t == -3 ) return -1;
		if ( t == 3 ) return 1;
	}
	for ( i = 0; i < 3; i ++ )
	{
		t = array[0][i] + array[1][i] + array[2][i];
		if ( t == -3 ) return -1;
		if ( t == 3 ) return 1;
	}
	int j = 0; t = 0;
	for ( i = 0; i < 3; i ++ )
	{
		j += array[i][i];
		t += array[i][2-i];
	}
	if ( t == -3 || j == -3 ) return -1;
	if ( t == 3 || j == 3 ) return 1;
	for ( i = 0; i < 3; i ++ )
	{
		for ( j = 0; j < 3; j ++ )
		{
			if ( array[i][j] == 0 ) return 6;
		}
	}
	return 0;
}    
    6.我另外加的一个 集Check 和Print 一起的函数,用来输出结果;

    代码:

int CP ( int array[3][3] )
{
	int t = Check ( array );
	Print ( array );
	if ( t == 0 )
	{
		printf ( "\t 平局!");
		system ( "pause" );
		return 0; 
	}
	if ( t == 1 )
	{
		printf ( "\t 恭喜你 赢了! ");
		system ( "pause" );
		return 0; 
	}
	if ( t == -1 )
	{
		printf ( "\t 很抱歉 输了! ");
		system ( "pause" );
		return 0; 
	}
	return -1;
} 
    7.主函数

    代码:

int main ( )
{
	system ( "title 井字棋小游戏--BY:nanshao_zz" ); 
	qgb ( );
	int array[3][3];
	memset ( array, 0, sizeof ( array ) );
	Print ( array );
	int x, y, t;
	while ( 1 )
	{
		scanf ( "%d %d", &x, &y );
		x --;
		y --;
		if ( x > 2 || y > 2 || x < 0 || y < 0 )
		{
			printf( "\t输入范围: 1-3! " );
			continue;
		}
		if ( IsNULL ( array, x, y ) == -1 )
		{
			printf ( "所选位置已存在! " );
			continue; 
		}
		array[x][y] = 1;
		t = CP ( array );
		if ( t == 0 ) return 0;
		GO ( array );
		t = CP ( array );
		if ( t == 0 ) return 0;
	}
	return 0;
} 

全部代码:

#include "algorithm"
#include "windows.h"
#include "iostream"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "vector"
#include "math.h"
#include "time.h"
#include "string"
#include "map" 

using namespace std;

//	去光标 
void qgb ( )	
{
	HANDLE handle = GetStdHandle ( STD_OUTPUT_HANDLE );  
	CONSOLE_CURSOR_INFO CursorInfo;  
	GetConsoleCursorInfo ( handle, &CursorInfo );
	CursorInfo.bVisible = false; 
	SetConsoleCursorInfo ( handle, &CursorInfo );
}

//	判断所选位置是否可下 不可下返回-1 可以下返回0 
int IsNULL ( int array[3][3], int x, int y )
{
	if ( array[x][y] == 0 ) return 0;
	return -1;
}

//	打印棋盘 
void Print ( int array[3][3] )
{
	system( "cls" );
	int i, j;
	printf ( "\n\n\t井 字 棋\n" );
	for ( i = 0; i < 3; i ++ )
	{				  
		printf ( "\n\t+-+-+-+\n\t|" );
		for ( j = 0; j < 3; j ++ )
		{
			if ( array[i][j] == 0 ) printf( " " );
			if ( array[i][j] == 1 ) printf( "X" );
			if ( array[i][j] == -1 ) printf( "O" );
			printf( "|" );
		}
	}
	printf ( "\n\t+-+-+-+\n\n" );
}

//	电脑下子 
int GO ( int array[3][3] )
{
	int i, t;
	int k;
	for ( i = 0; i < 3; i ++ )
	{
		t = array[i][0] + array[i][1] + array[i][2];
		if ( t == -2 )
		{
			for ( k = 0; k < 3; k ++ )
			{
				if ( array[i][k] == 0 )
				{
					array[i][k] = -1;
					return 0;
				} 
				
			}
		} 
	}
	for ( i = 0; i < 3; i ++ )
	{
		t = array[0][i] + array[1][i] + array[2][i];
		if ( t == -2 )
		{
			for ( k = 0; k < 3; k ++ )
			{
				if ( array[k][i] == 0 )
				{
					array[k][i] = -1;
					return 0;
				}
			}
		} 
	}
	int j = 0; t = 0;
	for ( i = 0; i < 3; i ++ )
	{
		j += array[i][i];
		t += array[i][2-i];
	}
	if ( t == -2 )
	{
		for ( k = 0; k < 3; k ++ )
		{
			if ( array[k][2-k] == 0 )
			{
				array[k][2-k] = -1;
				return 0;
			} 
		}
	}
	if ( j == -2 )
	{
		for ( k = 0; k < 3; k ++ )
		{
			if ( array[k][k] == 0 ) 
			{
				array[k][k] = -1;
				return 0;
			}
		}
	}
	
	
	
	for ( i = 0; i < 3; i ++ )
	{
		t = array[i][0] + array[i][1] + array[i][2];
		if ( t == 2 )
		{
			for ( k = 0; k < 3; k ++ )
			{
				if ( array[i][k] == 0 )
				{
					array[i][k] = -1;
					return 0;
				} 
				
			}
		} 
	}
	for ( i = 0; i < 3; i ++ )
	{
		t = array[0][i] + array[1][i] + array[2][i];
		if ( t == 2 )
		{
			for ( k = 0; k < 3; k ++ )
			{
				if ( array[k][i] == 0 )
				{
					array[k][i] = -1;
					return 0;
				}
			}
		} 
	}
	j = 0; t = 0;
	for ( i = 0; i < 3; i ++ )
	{
		j += array[i][i];
		t += array[i][2-i];
	}
	if ( t == 2 )
	{
		for ( k = 0; k < 3; k ++ )
		{
			if ( array[k][2-k] == 0 )
			{
				array[k][2-k] = -1;
				return 0;
			} 
		}
	}
	if ( j == 2 )
	{
		for ( k = 0; k < 3; k ++ )
		{
			if ( array[k][k] == 0 ) 
			{
				array[k][k] = -1;
				return 0;
			}
		}
	}
	
	
	while ( 1 )
	{
		srand ( time ( 0 ) );
		i = rand ( ) % 3;
		j = rand ( ) % 3;
		if ( IsNULL ( array, i, j ) == 0 )
		{
			array[i][j] = -1;
			break;
		}
	}
	return 0;
}

//	平局返回0;正方胜返回1;负反胜利返回-1;否则返回6; 
int Check ( int array[3][3] )
{
	int i, t;
	for ( i = 0; i < 3; i ++ )
	{
		t = array[i][0] + array[i][1] + array[i][2];
		if ( t == -3 ) return -1;
		if ( t == 3 ) return 1;
	}
	for ( i = 0; i < 3; i ++ )
	{
		t = array[0][i] + array[1][i] + array[2][i];
		if ( t == -3 ) return -1;
		if ( t == 3 ) return 1;
	}
	int j = 0; t = 0;
	for ( i = 0; i < 3; i ++ )
	{
		j += array[i][i];
		t += array[i][2-i];
	}
	if ( t == -3 || j == -3 ) return -1;
	if ( t == 3 || j == 3 ) return 1;
	for ( i = 0; i < 3; i ++ )
	{
		for ( j = 0; j < 3; j ++ )
		{
			if ( array[i][j] == 0 ) return 6;
		}
	}
	return 0;
}


int CP ( int array[3][3] )
{
	int t = Check ( array );
	Print ( array );
	if ( t == 0 )
	{
		printf ( "\t 平局!");
		system ( "pause" );
		return 0; 
	}
	if ( t == 1 )
	{
		printf ( "\t 恭喜你 赢了! ");
		system ( "pause" );
		return 0; 
	}
	if ( t == -1 )
	{
		printf ( "\t 很抱歉 输了! ");
		system ( "pause" );
		return 0; 
	}
	return -1;
} 

int main ( )
{
	system ( "title 井字棋小游戏--BY:nanshao_zz" ); 
	qgb ( );
	int array[3][3];
	memset ( array, 0, sizeof ( array ) );
	Print ( array );
	int x, y, t;
	while ( 1 )
	{
		scanf ( "%d %d", &x, &y );
		x --;
		y --;
		if ( x > 2 || y > 2 || x < 0 || y < 0 )
		{
			printf( "\t输入范围: 1-3! " );
			continue;
		}
		if ( IsNULL ( array, x, y ) == -1 )
		{
			printf ( "所选位置已存在! " );
			continue; 
		}
		array[x][y] = 1;
		t = CP ( array );
		if ( t == 0 ) return 0;
		GO ( array );
		t = CP ( array );
		if ( t == 0 ) return 0;
	}
	return 0;
} 
希望可以帮到正在学这个的你,欢迎批评指正!

你可能感兴趣的:(C/C++)