c# - 作业4:中国象棋

  • 总体视图 & 废话集结区
    • 资源下载
  • 代码(全)
    • FormMain.cs
    • Program.cs
    • Chess.cs
  • 现存bug

总体视图 & 废话集结区


印象里中国象棋 写的算是快的了,(因为会玩象棋/有意思哈哈哈哈

快人一步,快人步步

我在说什么哈哈哈哈,有趣

另外!!!敲重点!!!放上来的这个版本是封装完了的中国象棋//最开始张s老师教的应该是裸的中国象棋///但是后面会有一节课的时间专门讲封装的没记错的话应该是和“我们一起来抓虫”那个同一周搞得

记错了也是记错时间(因为当时我们班要讲这个课的时候张老师出差去了///后面也没有要补课的打算///所以///记错了也正常?吧- - -

资源下载

c# - 作业4:中国象棋,点击下载

代码(全)

FormMain.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Media;
namespace MyChess
{public partial class FormMain : Form{Chess chess = new Chess();//保存棋盘(细框)的左上角坐标private Point _leftTop = new Point(60, 60);//保存棋子半径private int _pieceR = 29;private int _dropRow = 0;private int _dropCol = 0;//保存当前所在点坐标private Point _curMousePoint = new Point(0, 0);private Color _markColor = Color.Yellow;//保存棋盘格子的行高和列数private int _rowHeight = 60;private int _colWidth = 60;private Bitmap _deskBmp = new Bitmap("desktop.jpg");//只装载一次,减少运行时间//保存红蓝双方14种棋子private Bitmap[] _pieceBmp = new Bitmap[15];//保存红方头像位图private Bitmap _redBmp = new Bitmap("红方头像.bmp");//保存蓝方头像位图private Bitmap _blueBmp = new Bitmap("蓝方头像.bmp");private void DrawBoard(Graphics g){g.DrawImage(_deskBmp, new Point(0, 0));Pen thickPen = new Pen(Color.Black, 6);Pen thinPen = new Pen(Color.Black, 2);int gap = (int)(_rowHeight * 0.15);g.DrawRectangle(thickPen, new Rectangle(_leftTop.X - gap, _leftTop.Y - gap, _colWidth * 8 + 2 * gap, _rowHeight * 9 + 2 * gap));for (int row = 1; row <= 10; row++){g.DrawLine(thinPen,new Point(_leftTop.X,_leftTop.Y+_rowHeight*(row-1)),new Point(_leftTop.X+8*_colWidth,_leftTop.Y+_rowHeight*(row-1)));}for (int col = 1; col <= 9; col++){g.DrawLine(thinPen, new Point(_leftTop.X + (col - 1) * _colWidth, _leftTop.Y),new Point(_leftTop.X + (col - 1) * _colWidth, _leftTop.Y + _rowHeight * 4));g.DrawLine(thinPen, new Point(_leftTop.X + (col - 1) * _colWidth, _leftTop.Y + _rowHeight * 5),new Point(_leftTop.X + (col - 1) * _colWidth, _leftTop.Y + _rowHeight * 9));}g.DrawLine(thinPen, new Point(_leftTop.X, _leftTop.Y + _rowHeight * 4),new Point(_leftTop.X, _leftTop.Y + _rowHeight * 5));g.DrawLine(thinPen, new Point(_leftTop.X + 8 * _colWidth, _leftTop.Y + _rowHeight * 4),new Point(_leftTop.X + 8 * _colWidth, _leftTop.Y + _rowHeight * 5));//上方九宫格交叉线g.DrawLine(thinPen,new Point(_leftTop.X + 3 * _colWidth,_leftTop.Y),new Point(_leftTop.X + 5 * _colWidth,_leftTop.Y + 2 * _rowHeight));g.DrawLine(thinPen,new Point(_leftTop.X + 5 * _colWidth, _leftTop.Y),new Point(_leftTop.X + 3 * _colWidth, _leftTop.Y + 2 * _rowHeight));g.DrawLine(thinPen,new Point(_leftTop.X + 3 * _colWidth, _leftTop.Y + 7 * _rowHeight),new Point(_leftTop.X + 5 * _colWidth, _leftTop.Y + 9 * _rowHeight));g.DrawLine(thinPen,new Point(_leftTop.X + 5 * _colWidth, _leftTop.Y + 7 * _rowHeight),new Point(_leftTop.X + 3 * _colWidth, _leftTop.Y + 9 * _rowHeight));Font font1 = new Font("隶书", (float)(_rowHeight * 0.8), FontStyle.Regular, GraphicsUnit.Pixel);SolidBrush brush = new SolidBrush(Color.Black);g.DrawString("楚河", font1, brush, new Point(_leftTop.X + _colWidth, (int)(_leftTop.Y + _rowHeight * 4.1)));g.DrawString("汉界", font1, brush, new Point(_leftTop.X + _colWidth * 5, (int)(_leftTop.Y + _rowHeight * 4.1)));Font font2 = new Font("黑体", (float)(_rowHeight * 0.6), FontStyle.Regular, GraphicsUnit.Pixel);for (int row = 1; row <= 10; row++){g.DrawString(row.ToString(), font2, brush, new Point((int)(_leftTop.X + _colWidth * 8.6),(int)(_leftTop.Y - _rowHeight * 0.4 + _rowHeight * (row - 1))));}string[] colNumber = new string[9]{"一","二","三","四","五","六","七","八","九"};Font font3 = new Font("黑体",(float)(_rowHeight*0.5),FontStyle.Regular,GraphicsUnit.Pixel);for(int col=1;col<=9;col++){g.DrawString(colNumber[col-1],font3,brush,new Point((int)(_leftTop.X-_colWidth*0.3+_colWidth*(col-1)),(int)(_leftTop.Y+_rowHeight*9.6)));}g.DrawString("蓝方",font3,brush,new Point(_leftTop.X+8*_colWidth+95,_leftTop.Y+(int)(2.2*_rowHeight)));g.DrawString("红方",font3,brush,new Point(_leftTop.X+8*_colWidth+95,_leftTop.Y+(int)(6.4*_rowHeight)));DrawCampMark(g, new Point(_leftTop.X + _colWidth * 1, _leftTop.Y + _rowHeight * 2), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 7, _leftTop.Y + _rowHeight * 2), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 0, _leftTop.Y + _rowHeight * 3), false, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 2, _leftTop.Y + _rowHeight * 3), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 4, _leftTop.Y + _rowHeight * 3), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 6, _leftTop.Y + _rowHeight * 3), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 8, _leftTop.Y + _rowHeight * 3), true, false);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 0, _leftTop.Y + _rowHeight * 6), false, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 2, _leftTop.Y + _rowHeight * 6), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 4, _leftTop.Y + _rowHeight * 6), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 6, _leftTop.Y + _rowHeight * 6), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 8, _leftTop.Y + _rowHeight * 6), true, false);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 1, _leftTop.Y + _rowHeight * 7), true, true);DrawCampMark(g, new Point(_leftTop.X + _colWidth * 7, _leftTop.Y + _rowHeight * 7), true, true);//绘制拾子位置的标记DrawPickDropMark(g, chess._pickRow, chess._pickCol);//绘制落子位置的标记DrawPickDropMark(g, _dropRow, _dropCol);//在相应的位置绘制走棋方的头像if (chess._curPlayer == Player.蓝)g.DrawImage(_blueBmp, new Point(_leftTop.X + 8 * _colWidth + 95, _leftTop.Y + 1 * _rowHeight - 10));else if (chess._curPlayer == Player.红)g.DrawImage(_redBmp, new Point(_leftTop.X + 8 * _colWidth + 95, _leftTop.Y + 7 * _rowHeight + 10));}//自定义:绘制炮和兵的营地标志public void DrawCampMark(Graphics g, Point center, Boolean drawLeft, Boolean drawRight){//偏移量和线段长度int offset = (int)(_rowHeight * 0.08), length = (int)(_rowHeight * 0.16);//直角坐标Point corner = new Point();//画笔对象Pen thinPen = new Pen(Color.Black, 1);//是否需要绘制左边标志if (drawLeft == true){corner.X = center.X - offset;corner.Y = center.Y - offset;g.DrawLine(thinPen, new Point(corner.X, corner.Y), new Point(corner.X - length, corner.Y));g.DrawLine(thinPen, new Point(corner.X, corner.Y), new Point(corner.X, corner.Y - length));corner.X = center.X - offset;corner.Y = center.Y + offset;g.DrawLine(thinPen, new Point(corner.X, corner.Y), new Point(corner.X - length, corner.Y));g.DrawLine(thinPen, new Point(corner.X, corner.Y), new Point(corner.X, corner.Y + length));}//是否需要绘制右边标志if (drawRight == true){corner.X = center.X + offset;corner.Y = center.Y - offset;g.DrawLine(thinPen, new Point(corner.X, corner.Y), new Point(corner.X + length, corner.Y));g.DrawLine(thinPen, new Point(corner.X, corner.Y), new Point(corner.X, corner.Y - length));corner.X = center.X + offset;corner.Y = center.Y + offset;g.DrawLine(thinPen, new Point(corner.X, corner.Y), new Point(corner.X + length, corner.Y));g.DrawLine(thinPen, new Point(corner.X, corner.Y), new Point(corner.X, corner.Y + length));}}public void DrawPiece(Graphics g){for (int row = 1; row <= 10; row++){for (int col = 1; col <= 9; col++){//如果该位子存在棋子if (chess._chess[row, col] != Piece.无子){//在棋盘交点绘制棋子g.DrawImage(_pieceBmp[(int)chess._chess[row, col]], new Point(_leftTop.X + (col - 1) * _colWidth - _pieceR, _leftTop.Y + (row - 1) * _rowHeight - _pieceR));}}}//在当前鼠标点位置绘制的棋子,以显示出拾起的棋子随鼠标而动的效果if (chess._pickChess != Piece.无子){g.DrawImage(_pieceBmp[(int)chess._pickChess], new Point(_curMousePoint.X - _pieceR, _curMousePoint.Y - _pieceR));}}//自定义类方法:把鼠标点击位置坐标转化成棋盘的行号和列号public bool ConvertPointToRowCol(Point p, out int row, out int col){//获取与鼠标点击位置距离最近的棋盘交叉的行号row = (p.Y - _leftTop.Y) / _rowHeight + 1;//如果鼠标点Y坐标超过棋盘行高的中线,则行号需要加1if (((p.Y - _leftTop.Y) % _rowHeight) >= _rowHeight / 2)row = row + 1;//获取与鼠标点击位置距离最近的棋盘交叉点的列号col = (p.X - _leftTop.X) / _colWidth + 1;//如果鼠标点x坐标超过棋盘列宽的中线,则列号需要加1if (((p.X - _leftTop.X) % _colWidth) >= _colWidth / 2)col = col + 1;//获取与鼠标点击位置距离最近的棋盘交叉点的坐标Point chessP = new Point();chessP.X = _leftTop.X + _colWidth * (col - 1);chessP.Y = _leftTop.Y + _rowHeight * (row - 1);//判断是否落在棋子半径之内,且在10行9列之内double dist = Math.Sqrt(Math.Pow(p.X - chessP.X, 2) + Math.Pow(p.Y - chessP.Y, 2));if ((dist <= _pieceR) && (row <= 10) && (row >= 1) && (col <= 9) && (col >= 1)){//返回true,表示该点击为有效点击return true;}else{//行号和列号设置为0,并返回false,表示该点击为无效点击row = 0; col = 0;return false;}}//自定义类方法:播放声音文件public void PlaySound(string wavFile){//装载声音文件(需要添加System.Media命名空间)SoundPlayer soundPlay = new SoundPlayer(wavFile);//使用新线程播放声音soundPlay.Play();//注意:soundPlay.PlaySync()也可以播放声音,该方法使用用户界面(UI)线程播放,会导致用户界面的停顿}public FormMain(){InitializeComponent();//根据屏幕的分辨率设置棋盘格子的行高和列宽_rowHeight = Screen.PrimaryScreen.Bounds.Size.Height / 13;_colWidth = _rowHeight;//设置棋盘上左上角坐标_leftTop.X = _leftTop.Y;_leftTop.Y = _rowHeight * 2;for (int i = 1; i <= 14; i++){_pieceBmp[i] = new Bitmap(((Piece)i).ToString() + ".bmp");_pieceBmp[i].MakeTransparent(Color.White);}//设置红蓝方头像位图的透明色_redBmp.MakeTransparent(Color.White);_blueBmp.MakeTransparent(Color.White);}//自定义类方法:绘制拾子或落子位置的标记public void DrawPickDropMark(Graphics g, int row, int col){if (row != 0){Pen pen = new Pen(Color.Yellow, 4);Point p = new Point(_leftTop.X + _colWidth * (col - 1), _leftTop.Y + _rowHeight * (row - 1));g.DrawLine(pen, p.X - _pieceR, p.Y - _pieceR, p.X - _pieceR / 2, p.Y - _pieceR);g.DrawLine(pen, p.X - _pieceR, p.Y - _pieceR, p.X - _pieceR, p.Y - _pieceR / 2);g.DrawLine(pen, p.X + _pieceR, p.Y - _pieceR, p.X + _pieceR / 2, p.Y - _pieceR);g.DrawLine(pen, p.X + _pieceR, p.Y - _pieceR, p.X + _pieceR, p.Y - _pieceR / 2);g.DrawLine(pen, p.X - _pieceR, p.Y + _pieceR, p.X - _pieceR / 2, p.Y + _pieceR);g.DrawLine(pen, p.X - _pieceR, p.Y + _pieceR, p.X - _pieceR, p.Y + _pieceR / 2);g.DrawLine(pen, p.X + _pieceR, p.Y + _pieceR, p.X + _pieceR / 2, p.Y + _pieceR);g.DrawLine(pen, p.X + _pieceR, p.Y + _pieceR, p.X + _pieceR, p.Y + _pieceR / 2);}}private void FormMain_Load(object sender, EventArgs e){}private void FormMain_Paint(object sender, PaintEventArgs e){DrawBoard(e.Graphics);DrawPiece(e.Graphics);}private void MenuItemBegin_Click(object sender, EventArgs e){if (MessageBox.Show("你是否需要开局?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes){//红方先走chess.Begin(Player.红);_dropRow = 0;_dropCol = 0;//使窗口失效,并发送paint消息,从而触发paint事件相应方法重绘棋盘和棋子Invalidate();PlaySound("Sounds\\begin.wav");}}private void FormMain_MouseDown(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left){//把鼠标点击位置设置为行号和列号int row, col;bool valid = ConvertPointToRowCol(new Point(e.X, e.Y), out row, out col);//判断鼠标点击是否有效if (valid == true){if (chess._curOperation == Operation.拾子){if (chess.PickChess(row, col) == true)chess._chess[row, col] = Piece.无子;}else if (chess._curOperation == Operation.落子){if (chess.DropChess(row, col) == true ){if (chess.IsOver() != Player.无){MessageBox.Show(chess.IsOver() + "赢了", "提示");}_dropRow = row;_dropCol = col;}}Invalidate();}}else if (e.Button == MouseButtons.Right){ if (chess.UndoPickChess() == true){chess._chess[chess._pickRow, chess._pickCol] = chess._pickChess;chess._pickRow = 0;chess._pickCol = 0;chess._pickChess = Piece.无子;}//强制刷新窗口Invalidate();}}private void FormMain_MouseMove(object sender, MouseEventArgs e){//保存当前鼠标所在点的坐标_curMousePoint = e.Location;//判断是否已经拾起棋子,以决定是否需要强制刷新窗口if (chess._pickChess != Piece.无子){Invalidate();}}private void MenuItemUndo_Click(object sender, EventArgs e){chess.UndoLastStep();}private void MenuItemSave_Click(object sender, EventArgs e){//显示保存残局对话框if (saveFileDialog1.ShowDialog() == DialogResult.OK){//创建一个文件流对剑,用于写文件(需要添加System.IO命名空间)                FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create);//创建一个文件流对象相对应的二进制写入流对象BinaryWriter bw = new BinaryWriter(fs);chess.WriteTo(bw);//关闭有关文件流对象bw.Close();fs.Close();}}private void MenuItemOpen_Click(object sender, EventArgs e){//显示打开残局对话框if (openFileDialog1.ShowDialog() == DialogResult.OK){//创建一个文件流对象,用于读文件FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);//创建一个与文件流对象相对应的二进制读入流对象BinaryReader br = new BinaryReader(fs);chess.ReadFrom(br);//关闭有关文件流对象br.Close();fs.Close();//强制刷新窗口(触发Paint事件)Invalidate();}}}
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;namespace MyChess
{static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(){Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new FormMain());}}
}

Chess.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;namespace MyChess
{//棋子枚举类型public enum Piece{无子 = 0,红车 = 1, 红马 = 2, 红相 = 3, 红士 = 4, 红帅 = 5, 红炮 = 6, 红卒 = 7,蓝车 = 8, 蓝马 = 9, 蓝象 = 10, 蓝士 = 11, 蓝将 = 12, 蓝炮 = 13, 蓝兵 = 14}public enum Player{无 = 0, 红 = 1, 蓝 = 2}//枚举类型 走棋操作public enum Operation{拾子, 落子}public class Step{public Player _player;public Piece _pickChess;public int _pickRow;public int _pickCol;public Piece _dropChess;public int _dropRow;public int _dropCol;}class Chess{//保存象棋棋盘所有棋子值public Piece[,] _chess = new Piece[11, 10];//保存当前的走棋方public Player _curPlayer = Player.无;//保存当前走棋操作public Operation _curOperation = Operation.拾子;//保存拾起的棋子public Piece _pickChess = Piece.无子;//保存拾起棋子的行号和列号public int _pickRow = 0;public int _pickCol = 0;//保存所有的走棋步骤public List<Step> _stepList = new List<Step>();public Step _lastStep{get{int stepCount = _stepList.Count;if (stepCount > 0)return _stepList[stepCount - 1];elsereturn null;}}//构造方法public Chess(){//调用象棋初始化方法Initialize();}//初始化方法public void Initialize(){//初始化当前的走棋方_curPlayer = Player.无;//初始化当前的走棋操作_curOperation = Operation.拾子;//保存拾起的棋子_pickChess = Piece.无子;//保存拾起棋子的行号和列号_pickRow = 0;_pickCol = 0;//清空list表中的走棋步骤_stepList.Clear();//把棋盘上棋子值都设为无子for (int i = 1; i <= 10; i++)for (int j = 1; j <= 9; j++){_chess[i, j] = Piece.无子;}}//类方法,象棋开局public void Begin(Player firstPlayer){//象棋初始化Initialize();//初始化当前走棋方_curPlayer = firstPlayer;//初始化蓝方棋子_chess[1, 1] = Piece.蓝车; _chess[1, 2] = Piece.蓝马; _chess[1, 3] = Piece.蓝象;_chess[1, 4] = Piece.蓝士; _chess[1, 5] = Piece.蓝将; _chess[1, 6] = Piece.蓝士;_chess[1, 7] = Piece.蓝象; _chess[1, 8] = Piece.蓝马; _chess[1, 9] = Piece.蓝车;_chess[3, 2] = Piece.蓝炮; _chess[3, 8] = Piece.蓝炮;_chess[4, 1] = Piece.蓝兵; _chess[4, 3] = Piece.蓝兵; _chess[4, 5] = Piece.蓝兵;_chess[4, 7] = Piece.蓝兵; _chess[4, 9] = Piece.蓝兵;//初始化红方棋子_chess[10, 1] = Piece.红车; _chess[10, 2] = Piece.红马; _chess[10, 3] = Piece.红相;_chess[10, 4] = Piece.红士; _chess[10, 5] = Piece.红帅; _chess[10, 6] = Piece.红士;_chess[10, 7] = Piece.红相; _chess[10, 8] = Piece.红马; _chess[10, 9] = Piece.红车;_chess[8, 2] = Piece.红炮; _chess[8, 8] = Piece.红炮;_chess[7, 1] = Piece.红卒; _chess[7, 3] = Piece.红卒; _chess[7, 5] = Piece.红卒;_chess[7, 7] = Piece.红卒; _chess[7, 9] = Piece.红卒;}//类方法,拾起棋子public bool PickChess(int pickRow, int pickCol){//如果当前走棋方不为无且走棋操作为拾子且拾起的是走棋方的棋子if (_curPlayer != Player.无 && _curOperation == Operation.拾子 &&_chess[pickRow, pickCol].ToString().IndexOf(_curPlayer.ToString()) == 0){//保存拾起的棋子值,行号和列号_pickChess = _chess[pickRow, pickCol];//保存拾子位置的行号和列号_pickRow = pickRow;_pickCol = pickCol;//切换走棋操作为落子_curOperation = Operation.落子;return true;}elsereturn false;}//类方法,落下棋子(true代表落子成功,false代表落子失败)public bool DropChess(int dropRow, int dropCol){//如果当前走棋方不为无且走棋操作为落子且规则验证成功if (_curPlayer != Player.无 && _curOperation == Operation.落子 &&MatchRules(_curPlayer, _pickRow, _pickCol, dropRow, dropCol) == true){//保存走棋步骤到_stepList中Step tempStep = new Step();tempStep._player = _curPlayer;tempStep._pickChess = _pickChess;tempStep._pickRow = _pickRow;tempStep._pickCol = _pickCol;tempStep._dropChess = _chess[dropRow, dropCol];tempStep._dropRow = dropRow;tempStep._dropCol = dropCol;_stepList.Add(tempStep);//落子位置设置为拾起位置的值_chess[dropRow, dropCol] = _pickChess;//清空拾子位置的棋子值_chess[_pickRow, _pickCol] = Piece.无子;//初始化拾起的棋子_pickChess = Piece.无子;//初始化拾起棋子的行号和列号_pickRow = 0;_pickCol = 0;//切换走棋步骤为拾子_curOperation = Operation.拾子;//切换走棋方if (_curPlayer == Player.红)_curPlayer = Player.蓝;else if (_curPlayer == Player.蓝)_curPlayer = Player.红;return true;}elsereturn false;}public bool UndoPickChess(){//如果当前走棋方不为无且已经拾起了棋子(即当前为落子)if (_curPlayer != Player.无 && _curOperation == Operation.落子){_curOperation = Operation.拾子;return true;}elsereturn false;}//悔棋(true代表成功,false代表失败)public bool UndoLastStep(){//获取走棋步骤数int stepCount = _stepList.Count;//判断是否存在走棋步骤if (stepCount > 0){//取出最后一部走棋信息Player player = _stepList[_stepList.Count - 1]._player;Piece pickChess = _stepList[_stepList.Count - 1]._pickChess;int pickRow = _stepList[_stepList.Count - 1]._pickRow;int pickCol = _stepList[_stepList.Count - 1]._pickCol;Piece dropChess = _stepList[_stepList.Count - 1]._dropChess;int dropRow = _stepList[_stepList.Count - 1]._dropRow;int dropCol = _stepList[_stepList.Count - 1]._dropCol;//删除最后一部走棋步骤_stepList.RemoveAt(_stepList.Count - 1);//还原走棋步骤_chess[pickRow, pickCol] = pickChess;_chess[dropRow, dropCol] = dropChess;//初始化走棋操作为拾子_curOperation = Operation.拾子;//初始化拾起的棋子_pickChess = Piece.无子;//初始化拾起棋子的行号和列号_pickRow = 0;_pickCol = 0;//设置当前的走棋方_curPlayer = player;return true;}elsereturn false;}//类方法判断象棋是否结束并返回获胜方public Player IsOver(){//获取走棋步骤数int stepCount = _stepList.Count;//判断是否存在走棋步骤if (stepCount > 0){//获取最后一步走棋步骤中落下或被吃的棋子Piece dropChess = _stepList[stepCount - 1]._dropChess;//判断落下棋子(被吃)棋子是否为帅if (dropChess == Piece.蓝将){//禁止继续下棋_curPlayer = Player.无;//返回获胜方return Player.红;}else if (dropChess == Piece.红帅){//禁止继续下棋_curPlayer = Player.无;//返回获胜方return Player.蓝;}elsereturn Player.无;}elsereturn Player.无;}//类方法:匹配走棋规则(true代表成功,false代表失败)public bool MatchRules(Player player, int pickRow, int pickCol, int dropRow, int dropCol){//定义一个匹配标志bool matchFlag = false;//如果走棋方不为无且拾起的是走棋方棋子且落子位置为无子或走棋方棋子if ( player != Player.无 && !(pickCol == dropCol && pickRow == dropRow)&& _pickChess.ToString().Substring(0, 1) == player.ToString()&& (_chess[dropRow, dropCol] == Piece.无子 || _chess[dropRow, dropCol].ToString().Substring(0, 1) != player.ToString())){//匹配车的走棋规则if (_pickChess == Piece.蓝车 || _pickChess == Piece.红车){//需要用到的局部变量申明bool blankFlag = false;int max, min;//如果横冲if (pickRow == dropRow){//比较起点列和落点列的大小max = dropCol > pickCol ? dropCol : pickCol;min = dropCol > pickCol ? pickCol : dropCol;//判断移动路径上棋子的是否全为无子blankFlag = true;for (int i = min + 1; i <= max - 1; i++){if (_chess[dropRow, i] != Piece.无子)blankFlag = false;}if (blankFlag == true)matchFlag = true;}//如果直撞if (pickCol == dropCol){//比较起点列和落点列的大小max = dropRow > pickRow ? dropRow : pickRow;min = dropRow > pickRow ? pickRow : dropRow;//判断移动路径上棋子的是否全为无子blankFlag = true;for (int i = min + 1; i <= max - 1; i++){if (_chess[i, dropCol] != Piece.无子)blankFlag = false;}if (blankFlag == true)matchFlag = true;}}//匹配马的走棋规则if (_pickChess == Piece.蓝马 || _pickChess == Piece.红马){//如果横着走日字且不拌马脚if (Math.Abs(pickRow - dropRow) == 1 && Math.Abs(pickCol - dropCol) == 2 &&_chess[pickRow, (pickCol + dropCol) / 2] == Piece.无子)matchFlag = true;//如果竖着走日字且不拌马脚if (Math.Abs(pickRow - dropRow) == 2 && Math.Abs(pickCol - dropCol) == 1 &&_chess[(pickRow + dropRow) / 2, pickCol] == Piece.无子)matchFlag = true;}//匹配象的走棋规则if (_pickChess == Piece.蓝象){//走田字,不拌象脚if (Math.Abs(pickRow - dropRow) == 2 && Math.Abs(pickCol - dropCol) == 2&& _chess[(pickRow + dropRow) / 2, (pickCol + dropCol) / 2] == Piece.无子 && dropRow <= 5)matchFlag = true;}if (_pickChess == Piece.红相){//走田字,不拌象脚if (Math.Abs(pickRow - dropRow) == 2 && Math.Abs(pickCol - dropCol) == 2&& _chess[(pickRow + dropRow) / 2, (pickCol + dropCol) / 2] == Piece.无子 && dropRow >= 6)matchFlag = true;}//匹配士的走棋规则if (_pickChess == Piece.蓝士){if (Math.Abs(pickRow - dropRow) == 1 && Math.Abs(pickCol - dropCol) == 1 && dropRow <= 3 && dropRow >= 1 && dropCol <= 6 && dropCol >= 4)matchFlag = true;}if (_pickChess == Piece.红士){if (Math.Abs(pickRow - dropRow) == 1 && Math.Abs(pickCol - dropCol) == 1 && dropRow <= 10 && dropRow >= 8 && dropCol <= 6 && dropCol >= 4)matchFlag = true;}//匹配红帅的走棋规则if (_pickChess == Piece.红帅){//如果在九宫格内移动if (((Math.Abs(pickRow - dropRow) == 1 && pickCol == dropCol) || (Math.Abs(pickCol - dropCol) == 1 && pickRow == dropRow)) && dropRow >= 8 && dropRow <= 10 && dropCol >= 4 && dropCol <= 6){matchFlag = true;}//如果两帅想面对面火拼if (_chess[dropRow, dropCol] == Piece.蓝将){//判断两帅是否在同一列上if (pickCol == dropCol){bool blankFlag = true;//检查两帅之间是否存在棋子for (int i = dropRow + 1; i <= pickRow - 1; i++){if (_chess[i, pickCol] != Piece.无子){blankFlag = false;break;}}if (blankFlag == true)matchFlag = true;}}}//匹配蓝将的走棋规则if (_pickChess == Piece.蓝将){//如果在九宫格内移动if (((Math.Abs(pickRow - dropRow) == 1 && pickCol == dropCol) || (Math.Abs(pickCol - dropCol) == 1 && pickRow == dropRow)) && dropRow >= 1 && dropRow <= 3 && dropCol >= 4 && dropCol <= 6){matchFlag = true;}//如果两帅想面对面火拼if (_chess[dropRow, dropCol] == Piece.红帅){//判断两帅是否在同一列上if (pickCol == dropCol){bool blankFlag = true;//检查两帅之间是否存在棋子for (int i = pickRow + 1; i <= dropRow - 1; i++){if (_chess[i, pickCol] != Piece.无子){blankFlag = false;break;}}if (blankFlag == true)matchFlag = true;}}}//匹配炮的走棋规则if (_pickChess == Piece.红炮 || _pickChess == Piece.蓝炮){//需要用到的局部变量申明bool blankFlag = false;int max, min;//如果落点存在棋子时if (_chess[dropRow, dropCol] != Piece.无子){//如果横着走if (pickRow == dropRow){//比较起点列和落点列的大小max = dropCol > pickCol ? dropCol : pickCol;min = dropCol < pickCol ? dropCol : pickCol;//统计移动路径上棋子的数量int chessNum = 0;for (int i = min + 1; i <= max - 1; i++){if (_chess[dropRow, i] != Piece.无子)chessNum++;}if (chessNum == 1)matchFlag = true;}//如果竖着走if (pickCol == dropCol){//比较起点列和落点列的大小max = dropRow > pickRow ? dropRow : pickRow;min = dropRow < pickRow ? dropRow : pickRow;//统计移动路径上棋子的数量int chessNum = 0;for (int i = min + 1; i <= max - 1; i++){if (_chess[i, dropCol] != Piece.无子)chessNum++;}if (chessNum == 1)matchFlag = true;}}//如果落点不存在棋子时if (_chess[dropRow, dropCol] == Piece.无子){//如果横着走if (pickRow == dropRow){//比较起点列和落点列的大小max = dropCol > pickCol ? dropCol : pickCol;min = dropCol < pickCol ? dropCol : pickCol;blankFlag = true;//检查两帅之间是否存在棋子for (int i = min + 1; i <= max - 1; i++){if (_chess[dropRow, i] != Piece.无子){blankFlag = false;}}if (blankFlag == true)matchFlag = true;}//如果竖着走if (pickCol == dropCol){//比较起点列和落点列的大小max = dropRow > pickRow ? dropRow : pickRow;min = dropRow < pickRow ? dropRow : pickRow;blankFlag = true;//检查两帅之间是否存在棋子for (int i = min + 1; i <= max - 1; i++){if (_chess[i, dropCol] != Piece.无子){blankFlag = false;}}if (blankFlag == true)matchFlag = true;}}}//匹配兵的走棋规则if (_pickChess == Piece.蓝兵){//不过河if (pickRow <= 5){if ((dropRow - pickRow) == 1 && (dropCol == pickCol))matchFlag = true;}//过河if (pickRow >= 6){//如果横着走if (dropRow == pickRow && Math.Abs(dropCol - pickCol) == 1)matchFlag = true;//如果竖着走if (dropCol == pickCol && (dropRow - pickRow) == 1)matchFlag = true;}}if (_pickChess == Piece.红卒){//不过河if (pickRow >= 6){if ((dropRow - pickRow) == -1 && (dropCol == pickCol))matchFlag = true;}//过河if (pickRow <= 5){//如果横着走if (dropRow == pickRow && Math.Abs(dropCol - pickCol) == 1)matchFlag = true;//如果竖着走if (dropCol == pickCol && (dropRow - pickRow) == -1)matchFlag = true;}}}return matchFlag;}//保存残局public void WriteTo(BinaryWriter binaryWriter){//保存当前的走棋方binaryWriter.Write(_curPlayer.ToString());//逐一保存棋盘上的棋子值for (int row = 1; row <= 10; row++){for (int col = 1; col <= 9; col++)binaryWriter.Write(_chess[row, col].ToString());}//保存走棋步骤的数量binaryWriter.Write(_stepList.Count);//逐一保存走棋步骤详细信息for (int i = 0; i <= _stepList.Count - 1; i++){binaryWriter.Write(_stepList[i]._player.ToString());binaryWriter.Write(_stepList[i]._pickChess.ToString());binaryWriter.Write(_stepList[i]._pickRow);binaryWriter.Write(_stepList[i]._pickCol);binaryWriter.Write(_stepList[i]._dropChess.ToString());binaryWriter.Write(_stepList[i]._dropRow);binaryWriter.Write(_stepList[i]._dropCol);}}//读取残局public void ReadFrom(BinaryReader binaryReader){//象棋初始化Initialize();//读取当前走棋方_curPlayer = (Player)Enum.Parse(typeof(Player), binaryReader.ReadString());//逐一读取棋盘上棋子for (int row = 1; row <= 10; row++)for (int col = 1; col <= 9; col++)_chess[row, col] = (Piece)Enum.Parse(typeof(Piece), binaryReader.ReadString());//读取走棋步骤数int stepCount = binaryReader.ReadInt32();//逐一读取走棋步骤详细信息for (int i = 0; i <= stepCount - 1; i++){Step step = new Step();step._player = (Player)Enum.Parse(typeof(Player), binaryReader.ReadString());step._pickChess = (Piece)Enum.Parse(typeof(Piece), binaryReader.ReadString());step._pickRow = binaryReader.ReadInt32();step._pickCol = binaryReader.ReadInt32();step._dropChess = (Piece)Enum.Parse(typeof(Piece), binaryReader.ReadString());step._dropRow = binaryReader.ReadInt32();step._dropCol = binaryReader.ReadInt32();//添加走棋步骤到列表_stepList.Add(step);}//设置当前走棋操作_curOperation = Operation.拾子;//初始化_pickChess = Piece.无子;_pickRow = _pickCol = 0;}}
}

现存bug

应该存在潜在bug?但是上次好像改掉了,可能还有也说不定,至少我/交作业之前/是没发现了

c# - 作业4:中国象棋相关推荐

  1. 【C++课程设计】期末大作业 - 基于Qt开发的中国象棋软件

    1 题目 基于Qt的中国象棋软件开发 本博客只是简略的描述论文的大致结构.框架,以及软件开发的大致过程.有兴趣的参考原文档资料. 2总体设计与主要功能 2.1概述 中国象棋是起源于中国的一种棋,属于二 ...

  2. 用turtle画中国象棋棋盘

    刚刚学习了<Python入门教程(一)--Python语言基础视频课程>(http://edu.51cto.com/course/12194.html) 中间有道作业就是用turtle画中 ...

  3. 基于Java+Swing实现中国象棋游戏

    基于Java+Swing实现中国象棋游戏 一.系统介绍 二.功能展示 三.其他系统 四.获取源码 前言 中国象棋是起源于中国的一种棋,属于二人对抗性游戏的一种,在中国有着悠久的历史.由于用具简单,趣味 ...

  4. 用C语言实现中国象棋(mac+windows双版本)

    今天突然翻到了大一上学期的c语言中国象棋大作业,想到这已经是我的编程水平巅峰,不由得心生悲哀,只好发出来记录一下. 零.前言 本程序已知的缺陷有:未能实现将/帅不能相对这一规则,其他bug暂时未知,建 ...

  5. C# - 课程流水线总结:计算器/计时器/我的画笔/中国象棋/坦克大战

    2020年6月末更新: 所有的源码我都传到GitHub上面去啦 点击前往GitHub 写博客这个事,还是要讲究时效性 今天补一下这学期上c#做的东西 计算器/计时器/我的画笔/中国象棋/坦克大战 第一 ...

  6. [源码和文档分享]基于Win32 API实现的中国象棋游戏

    一.选题 在<实践:程序设计实践>中选中了"中国象棋"为最后作业的题目. 中国象棋是一种交互性的.在固定大小的棋盘上进行的游戏,具有一定的规则来约束棋子的行走规律,同时 ...

  7. BZOJ 1801 [Ahoi2009]中国象棋(线性动规)(洛谷P2051)

    题意:就是在n*m的格子中放"炮"(中国象棋中的棋子)问有多少种放法,使得没有任意的两个炮相互攻击 思路:我们很容易的得到一列或者一行中最多放下两个炮(我也只能得到这些了,满脑子状 ...

  8. 使用Qt开发中国象棋(一):概述

    最近看了一些关于中国象棋的实现书籍,里面讲述了如何开发一个完整的中国象棋游戏,看了里面的内容,感觉里面的内容特别巧妙的,比如书中提到了用位棋盘来表示中国象棋的棋盘以及一些精妙的走棋算法.基于这些,自己 ...

  9. 中国象棋_通过设计国际象棋游戏来了解策略模式

    中国象棋 今天,我们将借助一个示例来尝试了解策略模式. 我们将考虑的示例是国际象棋游戏. 这里的目的是解释策略模式,而不是构建全面的国际象棋游戏解决方案. 策略模式:策略模式被称为行为模式–用于管理对 ...

最新文章

  1. 解题报告(一)C、(牛客练习赛41 F)简单数学题(数论 + FWT)(3.5)
  2. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(39)-在线人数统计探讨
  3. 5G推进阻力大 面临多利益方博弈
  4. java 超时集合_Java之集合(二十三)SynchronousQueue
  5. 大前端算法入门之二分查找
  6. linux中的权限对于文件和目录的重要性
  7. java project 项目在 linux 下面部署步骤
  8. 25个增强iOS应用程序性能的提示和技巧--高级篇
  9. 3.26 初接触Python
  10. ios vue 添加本地音乐_vue怎么添加自己的音乐
  11. 软件工程导论学习总结
  12. IDEA格式化js代码
  13. http隧道Chisel
  14. 电影《无双》中的管理知识
  15. matlab编写圆的公式,编写函数文件球半径为r的圆的面积周长 matlab
  16. 闰秒问题的全面解读与防范
  17. 计算机科学与技术光学成像专业,光信息科学与技术专业就业方向有哪些
  18. 大数据去重解决方案总结
  19. rational rose 2007安装破解全过程
  20. 今天跟好朋友的一段超长爆笑聊天记录(Space搬家)

热门文章

  1. MySQL内部函数介绍
  2. ruby中Thor用法雷神介绍,MyCLI < Thor详细介绍
  3. Oracle,UGA用户全局区域
  4. Spark RDD 论文详解(一)摘要和介绍
  5. v-for里面再嵌套一个v-for的写法
  6. Python 时间日期(datetime)
  7. 2005-04-21
  8. 蓝桥杯真题 14省3-李白打酒 话说大诗人李白,一生好饮。幸好他从不开车。 一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱: 无事街上走,提壶去打酒。 逢店加一倍,遇花喝一斗。 这一路上
  9. 使用Windows原生命令一键清空剪贴板
  10. pycharm alt+enter智能提示无法进行包导入