昨天学习了一个控制台五子棋的小程序,还是获益匪浅的,下面对这个小程序总结一下:
首先是要解决如何显示棋盘和显示棋子,这里我们用了一个二维数组借助图像“□”来布局棋盘,棋子用● 遍历二维数组并把“□”赋给二维数组的每一个元素就可以实现棋盘的显示了。
- 考虑到每盘棋下完后要初始化因此对棋盘进行初始化然后考虑如何把棋下到棋盘上呢?这一点我们利用屏幕的显示,只要屏幕上显示的是□就表示此处可以下棋●,
- 这样的话我们要做一个判断根据坐标来判断棋盘上的某个点是否为方框,这样有引出了新的问题就是找坐标的问题,在控制台了用户下棋需自己输入坐标位置的,因此获取用户的输入然后将其保存在数组中,再调用数组的Splict()方法即可。
- 接下来就要考虑怎么才能区别是谁下的子呢 这就要考虑棋子的属性 :形状一样大小一样只有颜色和位置不确定,但是位置是随机的很难把它找到并保存下来,所以考虑用颜色来做区别。想到了两种办法:1定义一个二维数组分别保存内容和颜色 2 定义棋子的枚举类型 将这个枚举定义为位枚举即在枚举的声明前加一个[Flags]。
- 接着就要判断输赢了,根据五子棋的原理,横向,纵向,斜对角的两个方向能连续的连成五个谁先连到谁就赢。还要注意边界的判断。
- 加入悔棋的思想::利用堆栈这个集合来存储下棋的位置,并提示落子者是否要悔棋,如果悔棋的话就把刚才他下的那一步POP出来,然后把那个位置置为□,并把颜色值为黑色,若果还要悔棋的话就POP++,我们可以控制下棋悔棋的部数,如最多3步
注意:1。循环的控制 用以个mark标志来处理,还要注意mark的位置
* 2 。还有就是将能封装成为一个方法的程序一定封装成一个方法
* 封装后前面定义的会成为局部变量 就会出错,这样的把他们都定义成方法的参数即可
* 3。 注意console.writeline和console.write的使用已经犯过两次这样的错误了
* 这个程序还包涵了控制台颜色和改变清空暂留等知识点,要熟练掌握,加油~!*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
namespace WuZiQI
{
class Program
{
//显示谁落的子的时候有两种办法:
//1定义数组分别存放内容和颜色
//2用位枚举
//□●
struct Point
{
public int X;
public int Y;
}
static void Main(string[] args)
{
//初始化棋盘
int length =20;
//int height = 20;
string[,] wuziqi=new string[length,length];//布局
ConsoleColor[,] consolecolor=new ConsoleColor[length,length];
for (int i = 0; i <length; i++)
{
for (int j = 0; j <length; j++)
{
wuziqi[i,j]="□";//
consolecolor[i,j]=ConsoleColor.Black;
}
}
下棋
ShowChess(wuziqi, consolecolor);
//落子
bool mark = false;
while (true)
{
//try
//{
if (XiaQi(wuziqi, consolecolor, ref mark))
{
ShowChess(wuziqi, consolecolor);
Console.WriteLine("赢了");
Thread.Sleep(500);
break;
}
//}
//catch (Exception ex)
//{
// Console.WriteLine(ex.Message);
//}
}
}
/// <summary>
/// 显示棋盘
/// </summary>,
/// <param name="wuziqi"></param>
static void ShowChess(string[,] wuziqi, ConsoleColor[,] consolecolor)
{
Console.Clear();
for (int i = 0; i < wuziqi.GetLength(0); i++)
{
for (int j = 0; j < wuziqi.GetLength(1); j++)
{
Console.ForegroundColor=consolecolor[i,j];
Console.Write(wuziqi[i, j]);
Console.ResetColor();
}
Console.WriteLine();
}
}
/// <summary>
/// 下棋落子
/// </summary>
/// <param name="wuziqi"></param>
/// <param name="consolecolor"></param>
/// <param name="mark"></param>
/// <returns></returns>
static bool XiaQi(string[,] wuziqi,ConsoleColor[,] consolecolor,ref bool mark)
{
ShowChess(wuziqi, consolecolor);
if (mark)
{
Console.Write("该甲落子啦");
}
else
{
Console.Write("该乙落子啦");
}
Console.WriteLine("请输入落子坐标:如8,6");
string location = Console.ReadLine();
string[] point = location.Split(',');//由于这里用数组来保存输入的坐标,因此输入8,6的话就是数组的索引下标为7,5,按数组的索引下标即为第7行第5列所以x轴为纵向的,y轴为横向的。
int x = int.Parse(point[0]) - 1;
int y = int.Parse(point[1]) - 1;
//悔棋
Point P = new Point();
P.X = x;
P.Y = y;
Stack<Point> sp = new Stack<Point>();
sp.Push(P);
bool aa = true;
ShowChess(wuziqi, consolecolor);
do
{
Console.Write("悔棋 Y 继续 N");
Console.WriteLine();
if (Console.ReadLine().ToUpper().ToString() == "Y")
{
Point p =sp.Pop();
wuziqi[P.X, P.Y] = "□";
consolecolor[P.X, P.Y] = ConsoleColor.Black;
ShowChess(wuziqi,consolecolor);
aa = true;
}
else
{
aa = false;
}
} while (aa);
if (wuziqi[x, y] == "□")
{
if (mark)
{
consolecolor[x, y] = ConsoleColor.Red;
}
else
{
consolecolor[x, y] = ConsoleColor.Blue;
}
mark = !mark;
wuziqi[x, y] = "●";
}
else
{
Console.WriteLine("sorry,这里不能放子了");
Thread.Sleep(500);
}
return (HWhoWin(consolecolor,x,y)||ZWhoWin(consolecolor,x,y)||ZXWhoWin(consolecolor,x,y)||YXWhoWin(consolecolor,x,y));
}
/// <summary>
/// 判断横向谁赢了
/// </summary>
///
//static int m = 1;//
static bool HWhoWin(ConsoleColor[,] consolecolor,int x,int y)//有人赢了就返回true
{
int m = 1;
ConsoleColor cc=consolecolor[x,y];
for (int i = 1; i < 5; i++)
{
if (y - i >= 0 && consolecolor[x , y - i] == cc)//横向y在变,x不变
{
m++;
}
else
{
break;
}
}
for (int i = 1; i < 5; i++)
{
if (y + i < consolecolor.GetLength(1)&&consolecolor[x,y+i] == cc)
{
m++;
}
else
{
break;
}
}
if (m >=5)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 判断纵向是否连成5个棋子
/// </summary>
/// <param name="consolecolor"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
static bool ZWhoWin(ConsoleColor[,] consolecolor, int x, int y)
{
int m = 1;
ConsoleColor cc =consolecolor[x,y];
for (int i = 1; i < 5; i++)
{
if (x - i >=0 && consolecolor[x-i, y ] == cc)
{
m++;
}
else
{
break;//不满足左边连成五个就要跳出往下进行,不break的话就一直在这个for循环里了
}
}
for (int i = 1; i < 5; i++)
{
if (x + i < consolecolor.GetLength(0) && consolecolor[x + i, y] == cc)
{
m++;
}
else
{
break;
}
}
if (m >=5)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 向左斜的方向
/// </summary>
/// <param name="consolecolor"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
static bool ZXWhoWin(ConsoleColor[,] consolecolor, int x, int y)
{
ConsoleColor cc=consolecolor[x,y];
int m = 1;
for (int i = 1; i < 5; i++)
{
if (x - i >= 0 && y - i >= 0&&x+i<consolecolor.GetLength(0) && consolecolor[x + i, y - i] == cc)
{
m++;
}
else
{
break;
}
}
for (int i = 1; i < 5; i++)
{
if (x-i>=0&& y+i<consolecolor.GetLength(1)&& consolecolor[x - i, y + i] == cc)
{
m++;
}
else
{
break;
}
}
if (m >= 5)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// y右斜方向
/// </summary>
/// <param name="consolecolor"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
static bool YXWhoWin(ConsoleColor[,] consolecolor, int x, int y)
{
int m = 1;
ConsoleColor cc=consolecolor[x,y];
for (int i = 1; i < 5; i++)
{
if (x - i >= 0 && y - i <= 0 &&consolecolor[x + i, y + i] == cc)
{
m++;
}
else
{
break;
}
}
for (int i = 1; i < 5; i++)
{
if (x + i < consolecolor.GetLength(0) && y + i < consolecolor.GetLength(1) && consolecolor[x + i, y + i] == cc)
{
m++;
}
else
{
break;
}
}
if (m >= 5)
{
return true;
}
else
{
return false;
}
}
}
转载于:https://blog.51cto.com/3333560/613006