您的当前位置:首页软著申请源代码之欧阳地创编

软著申请源代码之欧阳地创编

2020-06-17 来源:小侦探旅游网
欧阳地创编

前言

时间:2021.03.04

创作:欧阳地 围棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。同时它起源于中国,古称“弈”,是我国传统技艺之一。本游戏软件提供了人机对弈,和棋手对弈(局域网对弈)两种模式,局域网模式可以保证多人同时进行游戏。本软件使用C#语言编写,在windows 7 x64系统下采用Visual Studio 2010开发和调试,附源码如下。

客户端程序:

//-------------------login.cs---------// using System;

using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text;

using System.Windows.Forms; namespace go {

public partial class Login : Form {

public Login() {

InitializeComponent(); }

//人机对弈

private void button1_Click(object sender, EventArgs e)

{

欧阳地创编

欧阳地创编

this.Hide();

Playing playing = new Playing(); playing.ShowDialog(); this.Show(); }

//局域网对弈 private sender,EventArgs e)

{

this.Hide();

FormRoom formroom = new FormRoom(); formroom.ShowDialog(); this.Show(); }

private void button3_Click(object sender, EventArgs e)

{

Application.Exit(); }

private void button3_MouseEnter(object sender, EventArgs e)

{

Button btn = (Button)sender; btn.ForeColor = Color.Black; btn.BackColor = Color.White; }

private void button3_MouseLeave(object sender, EventArgs e)

{

Button btn = (Button)sender;

欧阳地创编

void button2_Click(object

欧阳地创编

btn.ForeColor = Color.White; btn.BackColor = Color.Black; } } } }

//-------------------Playing.cs---------// using System;

using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text;

using System.Windows.Forms; namespace go {

public partial class Playing : Form {

delegate void SetTextCallback(string text);

private enum Status {

NotStarted = 0, InGame = 1, RemoveDead = 2, FillEmpty = 3, Ended = 4 }

private System.Threading.Thread pc_play;

欧阳地创编

欧阳地创编

private Board m_board = new Board(); private Chess.ChessType Chess.ChessType.Black;

m_turn

=

private int m_secondsBlack = 0; private int m_secondsWhite = 0; private Timer m_timer = new Timer(); private Status.NotStarted;

{

get {

return m_turn; } set {

m_turn = value;

this.SetTurn((m_turn.ToString() == \"Black\") ? \"黑方\" : \"白方\");

} }

public Playing() {

InitializeComponent();

float h = this.Size.Height - 10; float w = this.Size.Width - 140; m_board.ReSize(0, 0, w, h); m_timer.Interval = 1000; m_timer.Tick EventHandler(timer_Tick);

欧阳地创编

Status m_status =

public Chess.ChessType turn

+= new

欧阳地创编

TimeSpan tm = new TimeSpan(0, 0, 0); labelTimeBlack.Text = tm.ToString(); labelTimeWhite.Text = tm.ToString(); labelTurn.Text = \"黑方\"; }

private void SetTurn(string text) {

if (this.labelTurn.InvokeRequired) {

SetTextCallback SetTextCallback(SetTurn);

this.Invoke(d, { text });

} else {

this.labelTurn.Text = text; } } //计时功能

private void timer_Tick(object sender, EventArgs e)

{

if (turn == Chess.ChessType.Black) {

m_secondsBlack++;

TimeSpan tm = new TimeSpan(0, 0, m_secondsBlack);

labelTimeBlack.Text tm.ToString();

欧阳地创编

d new

= new

object[]

=

欧阳地创编

}

else Chess.ChessType.White)

{

m_secondsWhite++;

TimeSpan tm = new TimeSpan(0, 0, m_secondsWhite);

labelTimeWhite.Text tm.ToString();

} if && !pc_play.IsAlive)

{

pc_play.Abort(); pc_play.Join(); pc_play = null; } }

private void OnFormClicked(object sender, EventArgs e)

{

//棋局结束

if (m_board.isGameOver) {

this.buttonCalculate_Click(null, null);

m_board.isGameOver = false; return; }

//不是轮到黑子的时候禁止下棋

if (!m_board.single || turn ==

欧阳地创编

if (turn ==

=

(pc_play != null

欧阳地创编

Chess.ChessType.White)

{

return; }

//备份棋局

this.m_board.BackupChess();

MouseEventArgs args = e as MouseEventArgs;

if (args != null) {

if (args.Clicks args.Button == MouseButtons.Left)

{

// 计算鼠标点击的坐标位置 Chess.POS pos m_board.mapPointsToBoard(args.X, args.Y);

if (pos.isValid) {

// 游戏中

if (m_status == Status.NotStarted || m_status == Status.InGame)

{

if (m_board.addChess(pos, turn))

{

turn = (turn == Chess.ChessType.Black) ? Chess.ChessType.White : Chess.ChessType.Black;

if (m_status == Status.NotStarted)

{

欧阳地创编

== 1 &&

=

欧阳地创编

m_timer.Start();

m_status = Status.InGame;

}

Invalidate(); } } if Status.RemoveDead)

{ m_board.toggleDead(pos);

Invalidate(); }

if (m_board.single)//人机对弈模式

{

pc_play = System.Threading.Thread(new

System.Threading.ThreadStart(ComputerPlay));

}

} } } }

delegate void ButtonDelegate(Button btn, bool flag);

private void SetButton(Button btn, bool flag)

{

欧阳地创编

(m_status ==

new

pc_play.Start();

欧阳地创编

if (btn.InvokeRequired) {

ButtonDelegate buttonDelegate = new ButtonDelegate(SetButton);

this.Invoke(buttonDelegate, new object[] { btn, flag });

} else {

btn.Enabled = flag; } }

private void ComputerPlay() {

//计算下一步棋

Chess.POS pos = m_board.Play(2, turn);

if (m_board.addChess(pos, turn)) {

turn = (turn == Chess.ChessType.Black) ? Chess.ChessType.White : Chess.ChessType.Black; if Status.NotStarted)

{

m_timer.Start();

m_status = Status.InGame; }

Invalidate(); } else

欧阳地创编

(m_status ==

欧阳地创编

{

//计算棋局结果

m_status = Status.FillEmpty; m_board.fillBoardWithChess(); string m_board.caclulateResult();

strResult

=

m_board.removeFilledChess(); MessageBox.Show(strResult, \"结果\");

m_board.single = false; this.SetButton false);

this.SetButton (this.btnLetOtherGo, false);

this.SetButton (this.btnAgain, false);

this.m_timer.Stop(); Invalidate(); } }

//显示棋子序号

private void checkBoxShowNumber_CheckedChanged(object sender, EventArgs e)

{

m_board.showIndex checkBoxShowNumber.Checked;

Invalidate(); }

//让子功能

private void buttonLetOtherGo_Click(object sender, EventArgs e)

欧阳地创编

(this.btnCalc,

=

欧阳地创编

{

if

Chess.ChessType.Black)

{

turn = Chess.oppsiteType(turn); if (m_board.single) {

pc_play = System.Threading.Thread(new

System.Threading.ThreadStart(ComputerPlay));

pc_play.Start(); } } }

//求和功能

private void buttonCalculate_Click(object sender, EventArgs e)

{

m_status = Status.FillEmpty; m_board.fillBoardWithChess(); string

m_board.caclulateResult();

strResult

= new

(this.turn

==

m_board.removeFilledChess();

MessageBox.Show(strResult, \"结果\"); m_board.single = false;

this.btnCalc.Enabled = false;

this.btnLetOtherGo.Enabled = false; this.btnAgain.Enabled = false; this.m_timer.Stop(); Invalidate();

欧阳地创编

欧阳地创编

}

//开始游戏 private void sender, EventArgs e)

{

DialogResult result = MessageBox.Show(\"确定要开始新游戏吗?\新游戏\MessageBoxButtons.YesNo);

if (result == DialogResult.Yes) {

m_board.newGame();

m_board.single = true;//人机对弈 m_secondsBlack = 0; m_secondsWhite = 0;

TimeSpan tm = new TimeSpan(0, 0, 0);

labelTimeBlack.Text tm.ToString();

labelTimeWhite.Text tm.ToString();

turn = Chess.ChessType.Black; m_timer.Stop();

m_board.markAllChessAsLive(); m_status = Status.NotStarted; this.btnCalc.Enabled = true; this.btnLetOtherGo.Enabled true;

this.btnAgain.Enabled = true; Invalidate(); } }

欧阳地创编

btnStart_Click(object

= =

=

欧阳地创编

//退出功能

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)

{

DialogResult result = MessageBox.Show(\"你确认要退出游戏吗?\\"提示\MessageBoxButtons.YesNo);

if (result == DialogResult.No) {

e.Cancel = true; } }

//主窗口大小

private void MainForm_SizeChanged(object sender, EventArgs e)

{

float h = this.Size.Height - 10; float w = this.Size.Width - 140; m_board.ReSize(0, 0, w, h); Invalidate(); }

//画棋盘

protected

OnPaint(PaintEventArgs e)

{

Graphics g = e.Graphics; m_board.draw(g); }

private void btnClose_Click(object sender, EventArgs e)

{

欧阳地创编

override void

欧阳地创编

this.Close(); }

//悔棋功能 private void sender, EventArgs e)

{

if (this.m_board.MoveAgain()) {

Invalidate(); } } } }

//------------------Board.cs---------// using System;

using System.Collections.Generic; using System.Text; using System.Drawing; using System.IO;

using ChessBlock = System.Collections.ArrayList; using System.Collections; namespace go {

///

/// 棋盘

///

public class Board {

///

欧阳地创编

btnAgain_Click(object

欧阳地创编

/// 单人模式 ///

public bool single = false; ///

/// 距离上方边缘的单位长度 ///

private static float margin_top = 10; ///

/// 距离左方边缘的单位长度 ///

private static float margin_left = 10; ///

/// 棋盘每条线之间的单位长度 ///

private static float gap = 20; ///

/// 棋子大小 ///

private static float chessSize = 8; ///

/// 数字字体大小 ///

private static float numberSize = 6; ///

/// 星位的大小 ///

private static float starSize = 3; ///

欧阳地创编

欧阳地创编

/// 棋盘的所有棋子 ///

private Chess[,] m_Board = new Chess[19, 19];

///

/// 棋盘备份 ///

private Chess[19, 19];Chess[,] m_Board_backup

///

/// 棋局记录对象 ///

private BoardRecorder m_recorder; ///

/// 最后一颗棋子 ///

private Chess m_LastChess; ///

/// 最后一个棋子备份 ///

private Chess m_LastChess_backup; ///

/// 最后一颗被吃的棋子 ///

private Chess m_LastEatten; ///

/// 最后被吃棋子备份 ///

private Chess m_LastEatten_backup;欧阳地创编

= new

欧阳地创编

///

/// 当前步数 ///

private int m_currentStep; ///

/// 是否显示棋子的编号 ///

private bool m_bShowIndex = false; ///

/// 模拟棋盘 ///

private Chess[,] m_Sim_Board = new Chess[19, 19];

///

/// 模拟最后一颗棋子 ///

private Chess m_Sim_LastChess; ///

/// 模拟最后一颗被吃的棋子 ///

private Chess m_Sim_LastEatten; ///

/// 模拟当前步数 ///

private int m_Sim_currentStep; ///

/// 参数随机数,用于参数随机棋步 ///

private Random r = new Random();

欧阳地创编

欧阳地创编

///

/// 棋局结束 ///

public bool isGameOver = false; ///

/// 创建棋盘 /// public Board() {

Clear(); }

///

/// 获取最后一颗棋子 ///

public Chess lastChess { get { return m_LastChess; } } ///

/// 获取或设置是否显示棋子的编号 ///

public bool showIndex {

get { return m_bShowIndex; } set { m_bShowIndex = value; } }

///

/// 调整棋子在棋盘中的位置,并返回棋子的位置

///

///

欧阳地创编

欧阳地创编

/// ///

public Chess.POS mapPointsToBoard(float pointX, float pointY) {

int posX = Convert.ToInt32((pointX - margin_left + gap / 2) / gap - 0.5f);

int posY = Convert.ToInt32((pointY - margin_top + gap / 2) / gap - 0.5f);

Chess.POS pos = new Chess.POS(posX, posY);

if (!pos.isValid)

pos.setToInvalid(); return pos; }

///

/// 绘制整个棋局 ///

/// public void draw(Graphics g) {

drawBorder(g); drawChess(g); }

///

/// 绘制星位 ///

/// /// ///

欧阳地创编

欧阳地创编

private void drawStar(Graphics g, float posX, float posY) {

Rectangle rect = new Rectangle(); rect.X = Convert.ToInt32 (margin_left + posX * gap - starSize);

rect.Y = Convert.ToInt32 (margin_top + posY * gap - starSize);

rect.Width = Convert.ToInt32 (starSize * 2);

rect.Height = Convert.ToInt32 (starSize * 2);

g.FillEllipse(Brushes.Black, rect); }

///

/// 绘制棋盘 ///

///

private void drawBorder(Graphics g) {

//绘制棋盘颜色

Pen backgroundPen Pen(Color.Goldenrod, 10);

=

new

g.FillRectangle(backgroundPen.Brush, margin_left - gap/2, margin_top - gap/2, gap * 19, gap * 19);

//绘制棋盘线

Pen borderPen = new Pen(Color.Black, 1); for (int i = 0; i < 19; i++) {

g.DrawLine(borderPen, margin_left, margin_top + i * gap, margin_left + 18 * gap,

欧阳地创编

欧阳地创编

margin_top + i * gap);

g.DrawLine(borderPen, margin_left + i * gap, margin_top, margin_left + i * gap, margin_top + 18 * gap); }

// 绘制9个星位 drawStar(g, 3, 3); drawStar(g, 3, 9); drawStar(g, 3, 15); drawStar(g, 9, 3); drawStar(g, 9, 9); drawStar(g, 9, 15); drawStar(g, 15, 3); drawStar(g, 15, 9); drawStar(g, 15, 15); }

///

/// 绘制棋子 ///

///

private void drawChess(Graphics g) {

Rectangle rect = new Rectangle(); StringFormat StringFormat();

format.Alignment StringAlignment.Center;

format.LineAlignment StringAlignment.Center;

format

=

new = =

Font fontNumber = new Font(\"Arial Narrow\

欧阳地创编

欧阳地创编

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

switch (m_Board[i, j].type) {

case Chess.ChessType.Black:

rect.X = Convert.ToInt32 (margin_left + i * gap - chessSize); rect.Y = Convert.ToInt32 (margin_top + j * gap - chessSize); rect.Width Convert.ToInt32 (chessSize * 2);

rect.Height Convert.ToInt32 (chessSize * 2);

g.FillEllipse(Brushes.Black, rect);

if (m_bShowIndex && m_Board[i, j].step > 0)

{

g.DrawString(m_Board[i, j].step.ToString(), fontNumber, Brushes.White, rect, format); } break; case Chess.ChessType.DeadBlack:

rect.X = Convert.ToInt32 (margin_left + i * gap - chessSize); rect.Y = Convert.ToInt32 (margin_top + j * gap - chessSize); rect.Width Convert.ToInt32 (chessSize * 2);

欧阳地创编

= =

=

欧阳地创编

rect.Height Convert.ToInt32 (chessSize * 2);

int centerX Convert.ToInt32 (margin_left + i * gap); int centerY Convert.ToInt32 (margin_top + j * gap);

g.FillEllipse(Brushes.Black, rect);

= = =

g.DrawLine(new

Pen(Color.Red, 3), centerX - chessSize / 2, centerY - chessSize / 2, centerX + chessSize / 2, centerY + chessSize / 2);

if (m_bShowIndex && m_Board[i, j].step > 0)

{

g.DrawString(m_Board[i, j].step.ToString(), fontNumber, Brushes.White, rect, format); } break; case Chess.ChessType.White:

rect.X = Convert.ToInt32 (margin_left + i * gap - chessSize); rect.Y = Convert.ToInt32 (margin_top + j * gap - chessSize); rect.Width Convert.ToInt32 (chessSize * 2);

rect.Height Convert.ToInt32 (chessSize * 2);

g.FillEllipse(Brushes.White, rect);

if (m_bShowIndex && m_Board[i, j].step > 0)

{

欧阳地创编

= =

欧阳地创编

g.DrawString(m_Board[i, j].step.ToString(), fontNumber, Brushes.Black, rect, format); } break; case Chess.ChessType.DeadWhite:

rect.X = Convert.ToInt32 (margin_left + i * gap - chessSize); rect.Y = Convert.ToInt32 (margin_top + j * gap - chessSize); rect.Width Convert.ToInt32 (chessSize * 2);

rect.Height Convert.ToInt32 (chessSize * 2);

centerX

Convert.ToInt32 (margin_left + i * gap); centerY Convert.ToInt32 (margin_top + j * gap);

g.FillEllipse(Brushes.White, rect);

g.DrawLine(new

Pen(Color.Red, 3), centerX - chessSize / 2, centerY - chessSize / 2, centerX + chessSize / 2, centerY + chessSize / 2);

if (m_bShowIndex && m_Board[i, j].step > 0)

{

g.DrawString(m_Board[i, j].step.ToString(), fontNumber, Brushes.Black, rect, format); } break; case Chess.ChessType.MaybeBlack:

欧阳地创编

= = = =

欧阳地创编

rect.X = Convert.ToInt32 (margin_left + i * gap - chessSize / 2);

rect.Y = Convert.ToInt32 (margin_top + j * gap - chessSize / 2);

rect.Width Convert.ToInt32 (chessSize);

rect.Height Convert.ToInt32 (chessSize);

g.FillRectangle(Brushes.Black, rect); break; case Chess.ChessType.MaybeWhite:

rect.X = Convert.ToInt32 (margin_left + i * gap - chessSize / 2);

rect.Y = Convert.ToInt32 (margin_top + j * gap - chessSize / 2);

rect.Width Convert.ToInt32 (chessSize);

rect.Height Convert.ToInt32 (chessSize);

g.FillRectangle(Brushes.White, rect); break; case Chess.ChessType.MaybePending:

rect.X = Convert.ToInt32 (margin_left + i * gap - chessSize / 2);

rect.Y = Convert.ToInt32 (margin_top + j * gap - chessSize / 2);

欧阳地创编

= =

= =

欧阳地创编

rect.Width Convert.ToInt32 (chessSize);

rect.Height Convert.ToInt32 (chessSize);

g.FillRectangle(Brushes.Yellow, rect); break; } } } }

///

/// 增加一颗棋子在棋盘上 ///

/// /// /// public bool Chess.ChessType type) {

if (this.m_currentStep > 361) {

this.isGameOver = true; return false; }

//只允许放黑棋或白棋

addChess(Chess.POS

= =

pos,

if (type != Chess.ChessType.Black && type != Chess.ChessType.White) return false;

// 只允许在空位置上放棋子。

欧阳地创编

欧阳地创编

if (m_Board[pos.posX, pos.posY].type != Chess.ChessType.Empty)

return false;

// 设置当前位置的棋子的类型

m_Board[pos.posX, pos.posY].type = type;

#region 判断是否可以提子 bool bEat = false; bool bValidStep = true;

//当棋子的左方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasLeft && m_Board[pos.posX - 1, pos.posY].type == Chess.oppsiteType(type)) { //

bEat = tryToEat(pos, new Chess.POS(pos.posX - 1, pos.posY), ref bValidStep) || bEat;

if (!bValidStep) return false; }

//当棋子的右方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasRight && m_Board[pos.posX + 1, pos.posY].type == Chess.oppsiteType(type)) {

bEat = tryToEat(pos, new Chess.POS(pos.posX + 1, pos.posY), ref bValidStep) || bEat;

if (!bValidStep) return false; }

欧阳地创编

欧阳地创编

//当棋子的上方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasUp && m_Board[pos.posX, pos.posY - 1].type == Chess.oppsiteType(type)) {

bEat = tryToEat(pos, new Chess.POS(pos.posX, pos.posY - 1), ref bValidStep) || bEat;

if (!bValidStep) return false; }

//当棋子的下方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasDown && m_Board[pos.posX, pos.posY + 1].type == Chess.oppsiteType(type)) {

bEat = tryToEat(pos, new Chess.POS(pos.posX, pos.posY + 1), ref bValidStep) || bEat;

if (!bValidStep) return false; }

#endregion if (!bEat)

m_LastEatten.pos.setToInvalid(); // 判断相连的棋子是否还有气。 ArrayList chessBlock;

if (!isLive(pos, out chessBlock)) {

return false; }

欧阳地创编

欧阳地创编

m_LastChess.pos = pos; m_LastChess.type = type;

m_LastChess.step = m_currentStep;

m_recorder.addStep(new Chess(pos, type, m_currentStep));

m_Board[pos.posX, pos.posY].step = m_currentStep;

m_Board[pos.posX, pos.posY].pos = pos; m_currentStep++; return true; }

///

/// 加载文件中的棋局 ///

/// /// public strFile) {

if

(!Utils.isFileReadyForRead(strFile)) return false;

Chess.ChessType[,] newBoard = new Chess.ChessType[19, 19]; StreamReader StreamReader(strFile); {

string freader.ReadLine();

strLine

=

freader

=

new

bool

loadBoardFromFile(string

for (int i = 0; i < 19; i++)

if (strLine.Length != 19)

欧阳地创编

欧阳地创编

return false;

for (int j = 0; j < 19; j++) {

Chess.ChessType Chess.ChessType.Empty;

switch (strLine[j]) {

case '0': type Chess.ChessType.Empty;

break; case '1': type Chess.ChessType.Black;

break; case '2': type Chess.ChessType.White;

break; default:

return false; }

newBoard[j, i] = type; } }

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

m_Board[i, j].type = newBoard[i,

欧阳地创编

type =

=

=

=

欧阳地创编

j];

} }

return true; }

///

/// 保存棋局到文件中 ///

/// ///

public bool saveBoardToFile(string strFile) {

FileInfo fi = new FileInfo(strFile); if (fi.Exists) fi.Delete();

StreamWriter sw = fi.CreateText(); for (int i = 0; i < 19; i++) {

StringBuilder StringBuilder(20); {

char ch;

ch = (m_Board[j, i].type == Chess.ChessType.Empty) ? '0' : (m_Board[j, i].type == Chess.ChessType.Black) ? '1' : '2'; strLine.Append(ch); }

sw.WriteLine(strLine);

欧阳地创编

strLine = new

for (int j = 0; j < 19; j++)

欧阳地创编

}

sw.Close(); return true; }

///

///

///

/// ///

public bool loadStepFile(string strFile) {

m_recorder.loadFromFile(strFile); int totalSteps = m_recorder.totalSteps; if (totalSteps > 0) {

clearBoard();

for (int i = 0; i < totalSteps; i++) {

Chess.POS m_recorder.getPosOfStep(i);

Chess.ChessType m_recorder.getTypeOfStep(i); }

return true; }

return false; }

///

欧阳地创编

pos type

= =

addChess(pos, type);

欧阳地创编

///

///

/// ///

public bool saveStepsToFile(string strFile) {

return m_recorder.saveToFile(strFile); }

///

/// 重新开局 ///

public void newGame() {

clear(); }

///

/// 填充棋子用以计算得分 ///

public void fillBoardWithChess() {

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

if (m_Board[i, j].type == Chess.ChessType.Empty) {

ChessBlock block;

findBlock(new Chess.POS(i,

欧阳地创编

欧阳地创编

j), out block);

if (block.Count > 0) {

Chess.ChessType type = Chess.ChessType.Empty;

foreach (Chess.POS pos in block)

{

if (pos.hasLeft) {

Chess.ChessType newType = m_Board[pos.posX - 1, pos.posY].type;

if (type == Chess.ChessType.Empty &&

(newType == Chess.ChessType.Black || newType == Chess.ChessType.White))

{

type newType;

} else {

if (type != Chess.ChessType.Empty &&

type == Chess.oppsiteType(newType))

{

type = Chess.ChessType.MaybePending;

break;

欧阳地创编

=

欧阳地创编

} } }

if (pos.hasRight) {

Chess.ChessType newType = m_Board[pos.posX + 1, pos.posY].type;

if (type == Chess.ChessType.Empty && (newType == Chess.ChessType.Black || newType == Chess.ChessType.White))

{

type newType;

} else {

if

(type != Chess.ChessType.Empty && type == Chess.oppsiteType(newType))

{

type = Chess.ChessType.MaybePending;

break;

} } }

if (pos.hasUp) {

Chess.ChessType newType = m_Board[pos.posX,

欧阳地创编

=

欧阳地创编

pos.posY - 1].type;

if (type == Chess.ChessType.Empty && (newType == Chess.ChessType.Black || newType == Chess.ChessType.White))

{

type newType;

} else {

if

(type != Chess.ChessType.Empty && type == Chess.oppsiteType(newType))

{

type = Chess.ChessType.MaybePending;

break;

} } }

if (pos.hasDown) {

Chess.ChessType newType = m_Board[pos.posX, pos.posY + 1].type;

if (type == Chess.ChessType.Empty && (newType == Chess.ChessType.Black || newType == Chess.ChessType.White))

{

type newType;

欧阳地创编

=

=

欧阳地创编

} else {

if

(type != Chess.ChessType.Empty && type == Chess.oppsiteType(newType))

{

type = Chess.ChessType.MaybePending;

break;

} } } } if Chess.ChessType.Black)

(type

== =

type Chess.ChessType.MaybeBlack;

else if (type == Chess.ChessType.White)

type Chess.ChessType.MaybeWhite; else type Chess.ChessType.MaybePending;

foreach posToFill in block)

{

m_Board[posToFill.posX, posToFill.posY].type = type;

}

欧阳地创编

=

=

(Chess.POS

欧阳地创编

} } } } }

///

/// 向虚拟棋盘填充棋子用以计算得分 ///

public void fillBoardWithChessOnSim() {

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

if (this.m_Sim_Board[i, j].type == Chess.ChessType.Empty) {

ChessBlock block; findBlockOnSim(new Chess.POS(i, j), out block);

if (block.Count > 0) {

Chess.ChessType type = Chess.ChessType.Empty;

foreach (Chess.POS pos in block)

{

if (pos.hasLeft) {

欧阳地创编

欧阳地创编

Chess.ChessType newType = this.m_Sim_Board[pos.posX - 1, pos.posY].type;

if (type == Chess.ChessType.Empty &&

(newType == Chess.ChessType.Black ||

newType == Chess.ChessType.White))

{

type newType;

} else {

if (type != Chess.ChessType.Empty &&

type == Chess.oppsiteType(newType))

{

type = Chess.ChessType.MaybePending;

break;

} } }

if (pos.hasRight) {

Chess.ChessType newType = this.m_Sim_Board[pos.posX + 1, pos.posY].type;

if (type == Chess.ChessType.Empty && (newType == Chess.ChessType.Black || newType ==

欧阳地创编

=

欧阳地创编

Chess.ChessType.White))

{

type newType;

} else {

if

(type != Chess.ChessType.Empty && type == Chess.oppsiteType(newType))

{ type = Chess.ChessType.MaybePending;

break;

} } }

if (pos.hasUp) {

Chess.ChessType newType = this.m_Sim_Board[pos.posX, pos.posY - 1].type;

if (type == Chess.ChessType.Empty && (newType == Chess.ChessType.Black || newType == Chess.ChessType.White))

{

type newType;

} else {

欧阳地创编

=

=

欧阳地创编

if

(type != Chess.ChessType.Empty && type == Chess.oppsiteType(newType))

{ type = Chess.ChessType.MaybePending;

break;

} } }

if (pos.hasDown) {

Chess.ChessType newType = this.m_Sim_Board[pos.posX, pos.posY + 1].type;

if (type == Chess.ChessType.Empty && (newType == Chess.ChessType.Black || newType == Chess.ChessType.White))

{

type newType;

} else {

if

(type != Chess.ChessType.Empty && type == Chess.oppsiteType(newType))

{

type = Chess.ChessType.MaybePending;

break;

欧阳地创编

=

欧阳地创编

} } } } if (type

== Chess.ChessType.Black)

type Chess.ChessType.MaybeBlack;

else Chess.ChessType.White)if

type Chess.ChessType.MaybeWhite; else type Chess.ChessType.MaybePending;

foreach posToFill in block)

{ this.m_Sim_Board[posToFill.posX, posToFill.posY].type = type; } } } } } }

///

///

///

public void removeFilledChess()欧阳地创编

=

== =

=

(type

(Chess.POS

欧阳地创编

{

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

if (m_Board[i, j].type == Chess.ChessType.MaybeBlack

|| m_Board[i, j].type == Chess.ChessType.MaybeWhite

|| m_Board[i, j].type == Chess.ChessType.MaybePending) {

m_Board[i, Chess.ChessType.Empty; } } } }

///

/// 暂停游戏,把棋子转换成死亡状态 ///

///

public void toggleDead(Chess.POS pos) {

Chess.ChessType type = m_Board[pos.posX, pos.posY].type;

if (type == Chess.ChessType.Black || type == Chess.ChessType.White ||

type == Chess.ChessType.DeadBlack || type == Chess.ChessType.DeadWhite) {

欧阳地创编

j].type =

欧阳地创编

ChessBlock block;

findBlock(pos, out block); if (block.Count > 0) {

Chess.ChessType typeResult = Chess.ChessType.Empty;

switch (type) {

case Chess.ChessType.Black:

typeResult Chess.ChessType.DeadBlack;

break; case Chess.ChessType.White:

typeResult Chess.ChessType.DeadWhite;

break; case Chess.ChessType.DeadBlack:

typeResult Chess.ChessType.Black;

break; case Chess.ChessType.DeadWhite:

typeResult Chess.ChessType.White;

break; }

foreach (Chess.POS posToToggle in block)

{

欧阳地创编

=

=

=

=

欧阳地创编

m_Board[posToToggle.posX, posToToggle.posY].type = typeResult; } } } }

///

/// 继续游戏,把棋子转换成存活状态 ///

public void markAllChessAsLive() {

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

if (m_Board[i, j].type == Chess.ChessType.DeadBlack) {

m_Board[i, Chess.ChessType.Black; }

else if (m_Board[i, j].type == Chess.ChessType.DeadWhite) {

m_Board[i, Chess.ChessType.White; } } } }

欧阳地创编

j].type =

j].type =

欧阳地创编

///

/// 计算棋局比分 ///

///

public string caclulateResult() {

int nBlack = 0; int nWhite = 0; int nPending = 0;

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

switch (m_Board[i, j].type) {

case Chess.ChessType.Black:

case Chess.ChessType.DeadWhite: case Chess.ChessType.MaybeBlack:

nBlack++; break; case Chess.ChessType.White:

case Chess.ChessType.DeadBlack: case Chess.ChessType.MaybeWhite:

nWhite++; break;

欧阳地创编

欧阳地创编

default:

nPending++; break; } } }

double fBlack (double)nPending / 2;

double fWhite (double)nPending / 2; StringBuilder StringBuilder();

= =

nBlack nWhite

=

+ + new

strResult

strResult.Append(\"黑子 : \" + fBlack.ToString() + \"\\n\");

strResult.Append(\"白子 : \" + fWhite.ToString() + \"\\n\\n\");

strResult.Append(\"结果 : \"); fWhite += 3.75; if (fBlack > fWhite) {

strResult.Append(\"黑子赢\" + (fBlack - fWhite).ToString()); }

else if (fWhite > fBlack) {

strResult.Append(\"白子赢\" + (fWhite - fBlack).ToString()); }

return strResult.ToString(); }

///

欧阳地创编

欧阳地创编

/// 初始化棋盘并创建新记录 ///

private void clear() {

clearBoard();

m_recorder = new BoardRecorder(); }

///

/// 初始化棋盘 ///

private void clearBoard() {

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

m_Board[i, j] = new Chess(new Chess.POS(i, j), Chess.ChessType.Empty, 0);

m_Board_backup[i, j] = new Chess(new Chess.POS(i, j), Chess.ChessType.Empty, 0); } }

m_LastChess = new Chess(); m_LastEatten = new Chess(); m_LastChess.pos.setToInvalid(); m_LastEatten.pos.setToInvalid(); m_currentStep = 1; }

欧阳地创编

欧阳地创编

private void clearMoveList() {

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

this.m_Sim_Board[i, j] = new Chess(new Chess.POS(i, j), Chess.ChessType.Empty, 0);

} } }

///

/// 搜索棋子块 ///

///

/// private void findBlock(Chess.POS pos, out ChessBlock chessBlock) {

Queue posToProcceed = new Queue(); chessBlock = new ArrayList(); posToProcceed.Enqueue(pos); chessBlock.Add(pos);

Chess.ChessType type = m_Board[pos.posX, pos.posY].type;

while (posToProcceed.Count > 0) {

Chess.POS posCurrent (Chess.POS)posToProcceed.Dequeue();

欧阳地创编

=

欧阳地创编

// Left

if (posCurrent.hasLeft) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX - 1, posCurrent.posY); if

(!posToProcceed.Contains(pos1)

&& !chessBlock.Contains(pos1) && m_Board[pos1.posX, pos1.posY].type == type) {

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } }

// Right

if (posCurrent.hasRight) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX + 1, posCurrent.posY); if

(!posToProcceed.Contains(pos1)

&& !chessBlock.Contains(pos1) && m_Board[pos1.posX, pos1.posY].type == type) {

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } } // Up

if (posCurrent.hasUp)

欧阳地创编

欧阳地创编

{

Chess.POS pos1 = new Chess.POS(posCurrent.posX, posCurrent.posY - 1); if

(!posToProcceed.Contains(pos1)

&& !chessBlock.Contains(pos1) && m_Board[pos1.posX, pos1.posY].type == type) {

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } }

// Down

if (posCurrent.hasDown) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX, posCurrent.posY + 1); if

(!posToProcceed.Contains(pos1)

&& !chessBlock.Contains(pos1) && m_Board[pos1.posX, pos1.posY].type == type) {

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } } } }

///

/// 搜索棋子块

欧阳地创编

欧阳地创编

///

///

/// private void findBlockOnSim(Chess.POS pos, out ChessBlock chessBlock) {

Queue posToProcceed = new Queue(); chessBlock = new ArrayList(); posToProcceed.Enqueue(pos); chessBlock.Add(pos);

Chess.ChessType type this.m_Sim_Board[pos.posX, pos.posY].type; while (posToProcceed.Count > 0) {

Chess.POS posCurrent (Chess.POS)posToProcceed.Dequeue(); // Left

if (posCurrent.hasLeft) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX - 1, posCurrent.posY); if

(!posToProcceed.Contains(pos1) && !chessBlock.Contains(pos1) &&

this.m_Sim_Board[pos1.posX, pos1.posY].type == type)

{

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); }

欧阳地创编

=

=

欧阳地创编

}

// Right

if (posCurrent.hasRight) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX + 1, posCurrent.posY); if

(!posToProcceed.Contains(pos1) && !chessBlock.Contains(pos1) &&

this.m_Sim_Board[pos1.posX, pos1.posY].type == type)

{

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } } // Up

if (posCurrent.hasUp) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX, posCurrent.posY - 1); if

(!posToProcceed.Contains(pos1) && !chessBlock.Contains(pos1) &&

this.m_Sim_Board[pos1.posX, pos1.posY].type == type)

{

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1);

欧阳地创编

欧阳地创编

} }

// Down

if (posCurrent.hasDown) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX, posCurrent.posY + 1); if

(!posToProcceed.Contains(pos1) && !chessBlock.Contains(pos1) &&

this.m_Sim_Board[pos1.posX, pos1.posY].type == type)

{

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } } } }

///

/// 判断棋子及相邻的棋子是否没气。 ///

///

/// ///

private bool isLive(Chess.POS pos, out ChessBlock chessBlock) {

// 1. 吃别人(包括劫持)

欧阳地创编

欧阳地创编

// 2. 被自己吃了

Queue posToProcceed = new Queue();//棋子位置队列

chessBlock = new ArrayList();//棋子位置块,用于记录最终所有相邻的同类的棋子位置

posToProcceed.Enqueue(pos);//把棋子位置添加到队列尾。

chessBlock.Add(pos);//把棋子位置添加到块里。

Chess.ChessType type = m_Board[pos.posX, pos.posY].type;//获取该位置棋子的类型

while (posToProcceed.Count > 0) {

Chess.POS posCurrent = (Chess.POS)posToProcceed.Dequeue();//获取队列的第一个棋子位置

//判断棋子与左边缘是否还有位置 if (posCurrent.hasLeft) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX - 1, posCurrent.posY); //左边相邻的位置没有棋子时,该棋子有气。返回true。

if (m_Board[pos1.posX, pos1.posY].type == Chess.ChessType.Empty) return true;

if

(!posToProcceed.Contains(pos1) && //该位置不在队列里

!chessBlock.Contains(pos1) && //该位置不在块里

m_Board[pos1.posX,

pos1.posY].type == type) //该位置的棋子类型与原棋子一样

欧阳地创编

欧阳地创编

{

//把该棋子添加到队列和块中。

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } }

//判断棋子与右边缘是否还有位置 if (posCurrent.hasRight) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX + 1, posCurrent.posY); //右边相邻的位置没有棋子时,该棋子有气。返回true。

if (m_Board[pos1.posX, pos1.posY].type == Chess.ChessType.Empty) return true;

if

(!posToProcceed.Contains(pos1) && //该位置不在队列里

!chessBlock.Contains(pos1) && //该位置不在块里

m_Board[pos1.posX,

pos1.posY].type == type) //该位置的棋子类型与原棋子一样

{

//把该棋子添加到队列和块中。

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); }

欧阳地创编

欧阳地创编

}

//判断棋子与上边缘是否还有位置 if (posCurrent.hasUp) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX, posCurrent.posY - 1); //上边相邻的位置没有棋子时,该棋子有气。返回true。

if (m_Board[pos1.posX, pos1.posY].type == Chess.ChessType.Empty) return true;

if

(!posToProcceed.Contains(pos1) && //该位置不在队列里

!chessBlock.Contains(pos1) && //该位置不在块里

m_Board[pos1.posX,

pos1.posY].type == type) //该位置的棋子类型与原棋子一样

{

//把该棋子添加到队列和块中。

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } }

//判断棋子与下边缘是否还有位置 if (posCurrent.hasDown) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX, posCurrent.posY + 1) //下边相邻的位置没有棋子时,该

欧阳地创编

欧阳地创编

棋子有气。返回true。

if (m_Board[pos1.posX, pos1.posY].type == Chess.ChessType.Empty) return true;

if

(!posToProcceed.Contains(pos1) && //该位置不在队列里

!chessBlock.Contains(pos1) && //该位置不在块里

m_Board[pos1.posX,

pos1.posY].type == type) //该位置的棋子类型与原棋子一样

{

//把该棋子添加到队列和块中。

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } } }

return false; }

///

/// 判断该棋子是否可以被吃。 ///

/// 刚下的棋子

/// 被吃的棋子

/// ///

欧阳地创编

欧阳地创编

private bool tryToEat(Chess.POS posNewChess, Chess.POS posToEat, ref bool bValidStep) {

bValidStep = true;

System.Collections.ArrayList chessBlock;

if (!isLive(posToEat, out chessBlock))//如果被吃棋子没气了,执行以下代码 {

// 处理打劫问题

if (chessBlock.Count == 1) {

if (m_LastEatten.pos.isValid && posNewChess == m_LastEatten.pos) {

removeChess(posNewChess); bValidStep = false; return false; } else {

m_LastEatten.pos posToEat;

} } else {

m_LastEatten.pos.setToInvalid(); }

removeChessBlock(chessBlock);

欧阳地创编

=

欧阳地创编

return true; }

return false; }

///

/// 提子(移出一组指定的棋子) ///

/// private void removeChessBlock(ChessBlock chessBlock) {

foreach (Chess.POS pos in chessBlock) {

m_Board[pos.posX, pos.posY].type = Chess.ChessType.Empty; } }

///

/// 提子(移出一颗指定的棋子) ///

///

private void removeChess(Chess.POS pos) {

m_Board[pos.posX, pos.posY].type = Chess.ChessType.Empty; }

///

/// 悔棋

///

欧阳地创编

欧阳地创编

public bool MoveAgain() {

if (this.m_currentStep > 1) {

//轮到自己下棋 if Chess.ChessType.White) {

for (int i = 0; i < 19; ++i) { for (int j = 0; j < 19; ++j) {

m_Board[i, j] = new Chess(m_Board_backup[i, j].pos, m_Board_backup[i, j].type, m_Board_backup[i, j].step); } }

this.m_LastChess this.m_LastChess_backup.Copy();

this.m_LastEatten this.m_LastEatten_backup.Copy();

this.m_currentStep -= 2; return true; }

//轮到电脑下棋 else {

//do nothing } }

欧阳地创编

(m_LastChess.type ==

= =

欧阳地创编

return false; }

public void BackupChess() {

for (int i = 0; i < 19; ++i) {

for (int j = 0; j < 19; ++j) {

m_Board_backup[i, j] = new Chess(m_Board[i, j].pos, m_Board[i, j].type, m_Board[i, j].step); } }

this.m_LastChess_backup this.m_LastChess.Copy();

this.m_LastEatten_backup this.m_LastEatten.Copy(); }

#region ==== 单人游戏时 ==== ///

/// 电脑开始计算下一步棋子 ///

/// /// /// public Chess.POS Chess.ChessType type) {

#region 添加候选步

//Chess.POS pos = this.m_LastChess.pos;

欧阳地创编

= =

Play(int numsim,

欧阳地创编

List List();

#region 一线点

move_Node = new

//根据经验规则选择比较合适的着法 if (this.m_LastChess.step > 20) {

#region 上边

for (int i = 0, j = 0; j < 19; ++j) {

if

(this.HaveChessDistantWithin(3, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion #region 下边

for (int i = 18, j = 0; j < 19; ++j) {

if

(this.HaveChessDistantWithin(3, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); }

欧阳地创编

欧阳地创编

}

#endregion #region 左边

for (int i = 1, j = 0; i < 18; ++i) {

if

(this.HaveChessDistantWithin(3, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion #region 右边

for (int i = 1, j = 18; i < 18; ++i) {

if

(this.HaveChessDistantWithin(3, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion }

欧阳地创编

欧阳地创编

#endregion #region 二线点

if (this.m_LastChess.step > 15) {

#region 上边

for (int i = 1, j = 1; j < 18; ++j) {

if

(this.HaveChessDistantWithin(4, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion #region 下边

for (int i = 17, j = 1; j < 18; ++j) {

if

(this.HaveChessDistantWithin(4, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

欧阳地创编

欧阳地创编

#endregion #region 左边

for (int i = 2, j = 1; i < 17; ++i) {

if

(this.HaveChessDistantWithin(4, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion #region 右边

for (int i = 2, j = 17; i < 17; ++i) {

if

(this.HaveChessDistantWithin(4, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion }

#endregion

欧阳地创编

欧阳地创编

#region 三线点

if (this.m_LastChess.step > 10) {

#region 上边

for (int i = 2, j = 2; j < 17; ++j) {

if

(this.HaveChessDistantWithin(4, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion #region 下边

for (int i = 16, j = 2; j < 17; ++j) {

if

(this.HaveChessDistantWithin(4, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion

欧阳地创编

欧阳地创编

#region 左边

for (int i = 3, j = 2; i < 16; ++i) {

if

(this.HaveChessDistantWithin(4, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion #region 右边

for (int i = 3, j = 16; i < 16; ++i) {

if

(this.HaveChessDistantWithin(4, i, j)) {

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } }

#endregion }

#endregion

for (int i = 3; i < 16; ++i)

欧阳地创编

欧阳地创编

{

for (int j = 3; j < 16; ++j) {

if (this.m_Board[i, j].type == Chess.ChessType.Empty &&

this.m_Board[i, j].step == 0)

{

if (this.CanAddChess(new Chess.POS(i, j), Chess.oppsiteType(m_LastChess.type)))

move_Node.Add(new Node(new Chess.POS(i, j))); } } }

if (move_Node.Count <= 0) {

this.isGameOver = true; }

#endregion

#region 每个节点都进行若干回合的模拟棋局

foreach (Node root in move_Node) {

for (int i = 0; i < numsim; ++i) {

CopyState(root); /* 复制棋局信息 */

play_simulation(root); /* 进行模拟 */

欧阳地创编

欧阳地创编

} }

#endregion

Node n = GetBestChild(move_Node); /* 获得根节点的访问次数最多的子节点 */

return n.pos; /* 返回节点着手 */ }

private bool CanAddChess(Chess.POS pos, Chess.ChessType type) {

//只允许放黑棋或白棋

if (type != Chess.ChessType.Black && type != Chess.ChessType.White) return false;

// 只允许在空位置上放棋子。

if (m_Board[pos.posX, pos.posY].type != Chess.ChessType.Empty)

return false;

// 设置当前位置的棋子的类型

m_Board[pos.posX, pos.posY].type = type;

#region 判断是否可以提子 bool bEat = false; bool bValidStep = true; bool result = true;

//当棋子的左方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasLeft && m_Board[pos.posX - 1, pos.posY].type == Chess.oppsiteType(type)) { //

欧阳地创编

欧阳地创编

bEat = ChecktryToEat(pos, new Chess.POS(pos.posX - 1, pos.posY), ref bValidStep) || bEat;

if (!bValidStep) result = false; }

//当棋子的右方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

else if (pos.hasRight m_Board[pos.posX + 1, pos.posY].type Chess.oppsiteType(type)) {

bEat = ChecktryToEat(pos, new Chess.POS(pos.posX + 1, pos.posY), ref bValidStep) || bEat;

if (!bValidStep) result = false; }

//当棋子的上方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

else if (pos.hasUp && m_Board[pos.posX, pos.posY - 1].type == Chess.oppsiteType(type)) {

bEat = ChecktryToEat(pos, new Chess.POS(pos.posX, pos.posY - 1), ref bValidStep) || bEat;

if (!bValidStep) result = false; }

//当棋子的下方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

else if (pos.hasDown m_Board[pos.posX, pos.posY + 1].type Chess.oppsiteType(type))

欧阳地创编

&& ==

&& ==

欧阳地创编

{

bEat = ChecktryToEat(pos, new Chess.POS(pos.posX, pos.posY + 1), ref bValidStep) || bEat;

if (!bValidStep) result = false; }

#endregion

// 判断相连的棋子是否还有气。 ArrayList chessBlock;

if (!isLive(pos, out chessBlock)) {

result= false; }

m_Board[pos.posX, pos.posY].type = Chess.ChessType.Empty; return result; }

private bool ChecktryToEat(Chess.POS posNewChess, Chess.POS posToEat, ref bool bValidStep) {

bValidStep = true;

System.Collections.ArrayList chessBlock;

if (!isLive(posToEat, out chessBlock))//如果被吃棋子没气了,执行以下代码 {

// 处理打劫问题

if (chessBlock.Count == 1) {

欧阳地创编

欧阳地创编

if (m_LastEatten.pos.isValid && posNewChess == m_LastEatten.pos) {

bValidStep = false; return false; } }

return true; }

return false; }

///

/// 小于某距离范围内是否有棋子 ///

/// /// ///

private bool HaveChessDistantWithin(int distant, int X, int Y) {

int x = 0, mx = 19; if (X- distant + 1 > 0) {

x = X - distant + 1; }

if (X + distant < 19) {

mx = X + distant; }

欧阳地创编

欧阳地创编

for (; x < mx; ++x) {

int y = 0, my = 19; if (Y - distant + 1 > 0) {

y = Y - distant + 1; }

if (Y + distant < 19) {

my = Y + distant; }

for (; y < my; ++y) {

if (Math.Abs(x - X) + Math.Abs(y - Y) >= distant)

continue;

if (this.m_Board[x, y].type != Chess.ChessType.Empty) {

return true; } } }

return false; }

private void CopyState(Node n) {

for (int i = 0; i < 19; ++i) {

欧阳地创编

欧阳地创编

for (int j = 0; j < 19; ++j) {

this.m_Sim_Board[i, j] = new Chess(this.m_Board[i, j].pos, this.m_Board[i, j].type, this.m_Board[i, j].step); } }

this.m_Sim_LastChess this.m_LastChess.Copy();

this.m_Sim_LastEatten this.m_LastEatten.Copy();

this.m_Sim_currentStep this.m_currentStep;

this.addChessOnSim(n.pos,

Chess.oppsiteType(this.m_Sim_LastChess.type)); }

///

/// 进行模拟 ///

///

private void play_simulation(Node n) {

Chess chs; do {

//随机创建棋步 chs = CreatePos(); //棋局结束

if (chs == null) break;

this.addChessOnSim(chs.pos,

欧阳地创编

= = =

欧阳地创编

chs.type);

} while (true); #region 填子

this.fillBoardWithChessOnSim(); #endregion

#region 计算分数 int nBlack = 0; int nWhite = 0; int nPending = 0;

for (int i = 0; i < 19; i++) {

for (int j = 0; j < 19; j++) {

switch j].type)

{

case Chess.ChessType.Black:

case Chess.ChessType.DeadWhite: case Chess.ChessType.MaybeBlack:

nBlack++; break; case Chess.ChessType.White:

case Chess.ChessType.DeadBlack: case Chess.ChessType.MaybeWhite:

nWhite++;

欧阳地创编

(this.m_Sim_Board[i,

欧阳地创编

break; default:

nPending++; break; } } }

double fBlack (double)nPending / 2;

double fWhite (double)nPending / 2;

fWhite += 3.75;

if ((fBlack > fWhite && this.m_LastChess.type==Chess .ChessType .White)|| (fBlack < fWhite && this.m_LastChess.type == Chess.ChessType.Black)) {

//是轮到黑方下棋,切此步黑方占优 //是轮到白方下棋,切此步白方占优 n.update_node(1); /* 更新节点信息 */ }

#endregion }

///

/// 随机生成下一步合法的棋子 ///

/// private Chess CreatePos() {

欧阳地创编

= =

nBlack nWhite

+ +

欧阳地创编

//获取棋盘所以可以下棋的空点

ArrayList emptyList = new ArrayList(); foreach (Chess c in this.m_Sim_Board) {

if (c.type == Chess.ChessType.Empty && c.step == 0) {

emptyList.Add(c); } }

if (emptyList.Count <= 0) return null;

Chess.ChessType type

Chess.oppsiteType(this.m_Sim_LastChess.type); Chess.POS pos ((Chess)emptyList[this.r.Next(0, emptyList.Count)]).pos;

= =

Chess chs = new Chess(pos, type, this.m_Sim_currentStep); return chs; }

///

/// 增加一颗棋子在模拟棋盘上 ///

/// /// ///

public bool addChessOnSim(Chess.POS pos, Chess.ChessType type) {

//只允许放黑棋或白棋

欧阳地创编

欧阳地创编

if (type != Chess.ChessType.Black && type != Chess.ChessType.White) return false;

// 只允许在空位置上放棋子。

if (this.m_Sim_Board[pos.posX, pos.posY].type != Chess.ChessType.Empty) return false;

// 设置当前位置的棋子的类型 this.m_Sim_Board[pos.posX, pos.posY].type = type;

#region 判断是否可以提子 bool bEat = false; bool bValidStep = true;

//当棋子的左方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasLeft && this.m_Sim_Board[pos.posX - 1, pos.posY].type == Chess.oppsiteType(type)) {

bEat = tryToEatOnSim(pos, new Chess.POS(pos.posX - 1, pos.posY), ref bValidStep) || bEat;

if (!bValidStep) return false; }

//当棋子的右方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasRight && this.m_Sim_Board[pos.posX + 1, pos.posY].type == Chess.oppsiteType(type)) {

bEat = tryToEatOnSim(pos, new Chess.POS(pos.posX + 1, pos.posY), ref bValidStep) || bEat;

欧阳地创编

欧阳地创编

if (!bValidStep) return false; }

//当棋子的上方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasUp && this.m_Sim_Board[pos.posX, pos.posY - 1].type == Chess.oppsiteType(type)) {

bEat = tryToEatOnSim(pos, new Chess.POS(pos.posX, pos.posY - 1), ref bValidStep) || bEat;

if (!bValidStep) return false; }

//当棋子的下方有空位,并且该位置棋子的棋子是对方的棋子时,执行以下代码

if (pos.hasDown && this.m_Sim_Board[pos.posX, pos.posY + 1].type == Chess.oppsiteType(type)) {

bEat = tryToEatOnSim(pos, new Chess.POS(pos.posX, pos.posY + 1), ref bValidStep) || bEat;

if (!bValidStep) return false; }

#endregion

if (!bEat)//把棋子移出棋盘

this.m_Sim_LastEatten.pos.setToInvalid(); // 判断相连的棋子是否还有气。 ArrayList chessBlock;

欧阳地创编

欧阳地创编

if (!isLiveOnSim(pos, out chessBlock)) {

if (type == Chess.ChessType.Black) this.m_Sim_Board[pos.posX, pos.posY].type = Chess.ChessType.DeadBlack; else Chess.ChessType.White)

if

(type

==

this.m_Sim_Board[pos.posX, pos.posY].type = Chess.ChessType.DeadWhite; return false;

//removeChessBlock(chessBlock); }

this.m_Sim_LastChess.pos = pos; this.m_Sim_LastChess.type = type; this.m_Sim_LastChess.step this.m_Sim_currentStep;

//m_recorder.addStep(new type, this.m_Sim_currentStep));

=

Chess(pos,

this.m_Sim_Board[pos.posX, pos.posY].step = this.m_Sim_currentStep; ++this.m_Sim_currentStep; return true; }

///

/// 判断该棋子是否可以被吃。 ///

/// 刚下的棋子

/// 被吃的棋子

///

欧阳地创编

欧阳地创编

///

private bool tryToEatOnSim(Chess.POS posNewChess, Chess.POS posToEat, ref bool bValidStep) {

bValidStep = true; ChessBlock chessBlock;

if (!isLiveOnSim(posToEat, out chessBlock))//如果被吃棋子没气了,执行以下代码 {

// deal with \"ko(dajie)\" if (chessBlock.Count == 1) {

if

(this.m_Sim_LastEatten.pos.isValid && posNewChess m_LastEatten.pos) {

removeChessOnSim(posNewChess);

bValidStep = false; return false; } else {

m_Sim_LastEatten.pos posToEat;

} } else {

欧阳地创编

==

=

欧阳地创编

m_Sim_LastEatten.pos.setToInvalid(); }

removeChessBlockOnSim(chessBlock); return true; }

return false; }

///

/// 判断棋子及相邻的棋子是否有气。 ///

///

/// ///

private bool isLiveOnSim(Chess.POS pos, out ChessBlock chessBlock) {

// two cases need to be handled // 1. Eat others (Include \"jie\") // 2. Be eaten yourself

Queue posToProcceed = new Queue();//棋子位置队列

chessBlock = new ArrayList();//棋子位置块,用于记录最终所有相邻的同类的棋子位置

posToProcceed.Enqueue(pos);//把棋子位置添加到队列尾。

chessBlock.Add(pos);//把棋子位置添加到块里。

Chess.ChessType type = this.m_Sim_Board[pos.posX, pos.posY].type;//获取该位置棋子的类型

欧阳地创编

欧阳地创编

while (posToProcceed.Count > 0) {

Chess.POS posCurrent = (Chess.POS)posToProcceed.Dequeue();//获取队列的第一个棋子位置

//判断棋子与左边缘是否还有位置 if (posCurrent.hasLeft) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX - 1, posCurrent.posY); //左边相邻的位置没有棋子时,该棋子有气。返回true。

if (this.m_Sim_Board[pos1.posX, pos1.posY].type == Chess.ChessType.Empty) return true;

if

(!posToProcceed.Contains(pos1) && //该位置不在队列里

!chessBlock.Contains(pos1) && //该位置不在块里

this.m_Sim_Board[pos1.posX, pos1.posY].type == type) //该位置的棋子类型与原棋子一样 {

//把该棋子添加到队列和块中。

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } }

//判断棋子与右边缘是否还有位置 if (posCurrent.hasRight)

欧阳地创编

欧阳地创编

{

Chess.POS pos1 = new Chess.POS(posCurrent.posX + 1, posCurrent.posY); //右边相邻的位置没有棋子时,该棋子有气。返回true。

if (this.m_Sim_Board[pos1.posX, pos1.posY].type == Chess.ChessType.Empty) return true;

if

(!posToProcceed.Contains(pos1) && //该位置不在队列里

!chessBlock.Contains(pos1) && //该位置不在块里

this.m_Sim_Board[pos1.posX, pos1.posY].type == type) //该位置的棋子类型与原棋子一样 {

//把该棋子添加到队列和块中。

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } }

//判断棋子与上边缘是否还有位置 if (posCurrent.hasUp) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX, posCurrent.posY - 1); //上边相邻的位置没有棋子时,该棋子有气。返回true。

if (this.m_Sim_Board[pos1.posX, pos1.posY].type == Chess.ChessType.Empty) return true;

欧阳地创编

欧阳地创编

if

(!posToProcceed.Contains(pos1) && //该位置不在队列里

!chessBlock.Contains(pos1) && //该位置不在块里

this.m_Sim_Board[pos1.posX, pos1.posY].type == type) //该位置的棋子类型与原棋子一样 {

//把该棋子添加到队列和块中。

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } }

//判断棋子与下边缘是否还有位置 if (posCurrent.hasDown) {

Chess.POS pos1 = new Chess.POS(posCurrent.posX, posCurrent.posY + 1); //下边相邻的位置没有棋子时,该棋子有气。返回true。

if (this.m_Sim_Board[pos1.posX, pos1.posY].type == Chess.ChessType.Empty) return true;

if

(!posToProcceed.Contains(pos1) && //该位置不在队列里

!chessBlock.Contains(pos1) && //该位置不在块里

this.m_Sim_Board[pos1.posX, pos1.posY].type == type) //该位置的棋子类型与原棋子一样

欧阳地创编

欧阳地创编

{

//把该棋子添加到队列和块中。

posToProcceed.Enqueue(pos1);

chessBlock.Add(pos1); } } }

return false; }

///

/// 模拟提子(移出一组指定的棋子) ///

/// private void removeChessBlockOnSim(ChessBlock chessBlock) {

foreach (Chess.POS pos in chessBlock) {

//this.m_Sim_Board[pos.posX, pos.posY].type = Chess.ChessType.Empty;

//上一步是黑子,当前是白子下棋,所以吃掉的棋子是黑子。

if (this.m_Sim_LastChess.type == Chess.ChessType.Black)

this.m_Sim_Board[pos.posX, pos.posY].type = Chess.ChessType.DeadBlack; else

this.m_Sim_Board[pos.posX, pos.posY].type = Chess.ChessType.DeadWhite;

欧阳地创编

欧阳地创编

} }

///

/// 模拟提子(移出一颗指定的棋子) ///

///

private void removeChessOnSim(Chess.POS pos) {

Chess.ChessType type this.m_Sim_Board[pos.posX, pos.posY].type; if (type == Chess.ChessType.Black) this.m_Sim_Board[pos.posX, pos.posY].type = Chess.ChessType.DeadBlack;

else if (type == Chess.ChessType.White) this.m_Sim_Board[pos.posX, pos.posY].type = Chess.ChessType.DeadWhite; }

///

/// 获取得分最高的候选棋步 ///

/// /// private move_Node) {

if (move_Node.Count <= 0) {

return null; }

欧阳地创编

=

Node GetBestChild(List

欧阳地创编

List temp1 = new List(); foreach (Node node in move_Node ) {

if (temp1.Count == 0) {

temp1.Add(node); }

else if (node.wins > temp1[0].wins) {

temp1.Clear(); temp1.Add(node); } else temp1[0].wins) {

temp1.Add(node); } }

List temp2 = new List(); foreach (Node node in temp1) {

Chess.POS pos = node.pos;

if

(Math.Abs(this.m_LastChess.pos.posX - pos.posX) <= 1 ||

Math.Abs(this.m_LastChess.pos.posY - pos.posY) <= 1)

{

temp2.Add(node);

欧阳地创编

if (node.wins ==

欧阳地创编

continue; }

if (this.HaveChessDistantWithin(3, pos.posX, pos.posY)) {

temp2.Add(node); } } Node result ; if (temp2.Count > 0) result 1)];

else result 1)]; return result; } #endregion ==== ///

/// /// /// /// /// /// public width, float height) { if (width > height) {

= temp2[r.Next(temp2.Count -

= temp1[r.Next(temp1.Count -

单人游戏时 ====

重新计算棋盘大小,以适应窗体的大小变化

开始位置横坐标 开始位置纵坐标 长度 高度 void ReSize(float x,float y,float

欧阳地创编

欧阳地创编

float v = height / 21; margin_top = y + v ;

margin_left = x + v + (width - height) / 2;

gap = v;

chessSize = 3 * v / 7; numberSize = 2 * v / 5; starSize = v / 5; } else {

float v = width / 21;

margin_top = y + v + (height - width) / 2;

margin_left = x + v; gap = v;

chessSize = 3 * v / 7; numberSize = 2 * v / 5; starSize = v / 5; } } } } /

服务端程序:

//-------------User.cs----------------// using System.Net.Sockets; using System.IO; namespace GameServer

欧阳地创编

欧阳地创编

{

class User {

public TcpClient client; public StreamReader sr; public StreamWriter sw; public string userName;

public User(TcpClient client) {

this.client = client; this.userName = \"\"; NetworkStream client.GetStream();

netStream

=

sr = new StreamReader(netStream, System.Text.Encoding.UTF8);

sw = new StreamWriter(netStream, System.Text.Encoding.UTF8); } } }

//-------------FormServer.cs------------------// using System;

using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text;

using System.Windows.Forms; //添加的命名空间

欧阳地创编

欧阳地创编

using System.Net;

using System.Net.Sockets; using System.Threading; using System.IO; namespace GameServer {

public partial class FormServer : Form {

//游戏室允许进入的最多人数 private int maxUsers; //连接的用户

System.Collections.Generic.List userList = new List(); //游戏室开出的桌数。 private int maxTables;

private GameTable[] gameTable; //使用的本机IP地址 IPAddress localAddress; //监听端口

private int port = 51888;

private TcpListener myListener; private Service service; public FormServer() {

InitializeComponent();

service = new Service(listBox1); }

//加载窗体时触发的事件

private void FormServer_Load(object sender,

欧阳地创编

欧阳地创编

EventArgs e) {

listBox1.HorizontalScrollbar = true; IPAddress[] addrIP Dns.GetHostAddresses(Dns.GetHostName()); localAddress = addrIP[0]; buttonStop.Enabled = false; }

//【开始服务】按钮的Click事件 private void sender, EventArgs e) {

if (int.TryParse(textBoxMaxTables.Text, out maxTables) == false

||

int.TryParse(textBoxMaxUsers.Text, out maxUsers) == false)

{

MessageBox.Show(\"请输入在规定范围内的正整数\");

return; }

if (maxUsers < 1 || maxUsers > 300) {

MessageBox.Show(\"允许进入的人数只能在1-300之间\");

return; }

if (maxTables < 1 || maxTables > 100) {

MessageBox.Show(\"允许的桌数只能在

欧阳地创编

=

buttonStart_Click(object

欧阳地创编

1-100之间\");

return; }

textBoxMaxUsers.Enabled = false; textBoxMaxTables.Enabled = false; //初始化数组

gameTable = new GameTable[maxTables]; for (int i = 0; i < maxTables; i++) {

gameTable[i] GameTable(listBox1); }

myListener = TcpListener(localAddress, port); myListener.Start();

service.SetListBox(string.Format(\"开始在{0}:{1}监听客户连接\ //创建一个线程监听客户端连接请求 ThreadStart ts ThreadStart(ListenClientConnect); myThread.Start();

buttonStart.Enabled = false; buttonStop.Enabled = true; }

//【停止服务】按钮的Click事件

private void buttonStop_Click(object sender, EventArgs e) {

//停止向游戏桌发送棋子

欧阳地创编

= new

new

= new

Thread myThread = new Thread(ts);

欧阳地创编

service.SetListBox(string.Format(\"目前连接用户数:{0}\

service.SetListBox(\"开始停止服务,并依次使用户退出!\");

for (int i = 0; i < userList.Count; i++) {

//关闭后,客户端接收字符串为null, //使接收该客户的线程ReceiveData接收的字符串也为null,

//从而达到结束线程的目的 userList[i].client.Close(); }

//通过停止监听让myListener.AcceptTcpClient()产生异常退出监听线程 myListener.Stop();

buttonStart.Enabled = true; buttonStop.Enabled = false; textBoxMaxUsers.Enabled = true; textBoxMaxTables.Enabled = true; }

//接收客户端连接

private void ListenClientConnect() {

while (true) {

TcpClient newClient = null; try {

//等待用户进入 newClient

欧阳地创编

=

欧阳地创编

myListener.AcceptTcpClient(); } catch {

//当单击“停止监听”或者退出此窗体时AcceptTcpClient()会产生异常

//因此可以利用此异常退出循环 break; }

//每接受一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息

ParameterizedThreadStart pts = new ParameterizedThreadStart(ReceiveData); Thread Thread(pts);

threadReceive

=

new

User user = new User(newClient); threadReceive.Start(user); userList.Add(user);

service.SetListBox(string.Format(\"{0}newClient.Client.RemoteEndPoint));

\

service.SetListBox(string.Format(\"当前连接用户数:{0}\ } }

//接收、处理客户端信息,每客户1个线程,参数用于区分是哪个客户

private void ReceiveData(object obj) {

User user = (User)obj;

TcpClient client = user.client;

欧阳地创编

欧阳地创编

//是否正常退出接收线程 bool normalExit = false; //用于控制是否退出循环 bool exitWhile = false; while (exitWhile == false) {

string receiveString = null; try {

receiveString user.sr.ReadLine(); } catch {

//该客户底层套接字不存在时会出现异常

service.SetListBox(\"接收数据失败\");

}

//TcpClient对象将套接字进行了封装,如果TcpClient对象关闭了,

//但是底层套接字未关闭,并不产生异常,但是读取的结果为null

if (receiveString == null) {

if (normalExit == false) {

//如果停止了监听,Connected为false

if (client.Connected == true)

欧阳地创编

=

欧阳地创编

{

service.SetListBox(string.Format(

\"与{0}失去联系,已终止接收该用户信息\

client.Client.RemoteEndPoint)); }

//如果该用户正在游戏桌上,则退出游戏桌

RemoveClientfromPlayer(user); }

//退出循环 break; }

service.SetListBox(string.Format(\"来自{0}:{1}\user.userName, receiveString)); string[] receiveString.Split(',');

splitString

=

int tableIndex = -1; //桌号 int side = -1; //座位号 int anotherSide = -1; //对方座位号

string sendString = \"\"; switch (splitString[0]) {

case \"Login\":

//格式:Login,昵称 //该用户刚刚登录 if

欧阳地创编

(userList.Count >

欧阳地创编

maxUsers)

{

sendString = \"Sorry\";

service.SendToOne(user, sendString);

service.SetListBox(\"人数已满,拒绝\" +

splitString[1] + \"进入游戏室\");

exitWhile = true; } else

//将用户昵称保存到用户列表中

//由于是引用类型,因此直接给user赋值也就是给userList中对应的user赋值

//用户名中包含其IP和端口的目的是为了帮助理解,实际游戏

//中一般不会显示IP的 user.userName string.Format(\"[{0}--{1}]\ client.Client.RemoteEndPoint);

//允许该用户进入游戏室,即将各桌是否有人情况发送给该用户

sendString = \"Tables,\" + this.GetOnlineString();

service.SendToOne(user, sendString); } break; case \"Logout\": //格式:Logout

欧阳地创编

=

欧阳地创编

//用户退出游戏室

service.SetListBox(string.Format(\"{0}退出游戏室\user.userName));

normalExit = true; exitWhile = true; break; case \"SitDown\":

//格式:SitDown,桌号,座位号

//该用户坐到某座位上 tableIndex int.Parse(splitString[1]); side int.Parse(splitString[2]);

gameTable[tableIndex].gamePlayer[side].user user;

= = =

gameTable[tableIndex].gamePlayer[side].someone = true;

service.SetListBox(string.Format(

\"{0}在第{1}桌第{2}座入座\

user.userName, tableIndex + 1, side + 1));

//得到对家座位号

anotherSide = (side + 1) % 2;

//判断对方是否有人

if

(gameTable[tableIndex].gamePlayer[anotherSide].someone == true)

欧阳地创编

欧阳地创编

{

//先告诉该用户对家已经入座

//发送格式:SitDown,座位号,用户名

sendString

string.Format(\"SitDown,{0},{1}\

=

gameTable[tableIndex].gamePlayer[anotherSide].user.userName);

service.SendToOne(user, sendString); }

//同时告诉两个用户该用户入座(也可能对方无人)

//发送格式:SitDown,座位号,用户名

sendString string.Format(\"SitDown,{0},{1}\user.userName);

service.SendToBoth(gameTable[tableIndex], sendString);

//重新将游戏室各桌情况发送给所有用户

service.SendToAll(userList, this.GetOnlineString());

break; case \"GetUp\":

//格式:GetUp,桌号,座位号 //用户离开座位,回到游戏室 tableIndex int.Parse(splitString[1]); side

欧阳地创编

= side,

\"Tables,\" +

= =

欧阳地创编

int.Parse(splitString[2]);

service.SetListBox(

string.Format(\"{0}离座,返回游戏室\

//将离座信息同时发送给两个用户,以便客户端作离座处理

//发送格式:GetUp,座位号,用户名

service.SendToBoth(gameTable[tableIndex], string.Format(\"GetUp,{0},{1}\user.userName));

//服务器进行离座处理

gameTable[tableIndex].gamePlayer[side].someone = false;

gameTable[tableIndex].gamePlayer[side].started = false;

gameTable[tableIndex].gamePlayer[side].grade = 0; anotherSide = (side + 1) % 2;

if

(gameTable[tableIndex].gamePlayer[anotherSide].someone == true)

{

gameTable[tableIndex].gamePlayer[anotherSide].started = false;

gameTable[tableIndex].gamePlayer[anotherSide].grade = 0;

}

//重新将游戏室各桌情况发

欧阳地创编

side,

欧阳地创编

送给所有用户

service.SendToAll(userList, this.GetOnlineString());

break; case \"Level\":

//格式:Time,桌号,难度级别 //设置难度级别 break; case \"Talk\":

//格式:Talk,桌号,对话内容 tableIndex int.Parse(splitString[1]);

=

\"Tables,\"

+

//由于说话内容可能包含逗号,所以需要特殊处理

sendString

string.Format(\"Talk,{0},{1}\

receiveString.Substring(splitString[0].Length + splitString[1].Length));

service.SendToBoth(gameTable[tableIndex], sendString);

break; case \"Ready\":

//格式:Start,桌号,座位号 //该用户单击了开始按钮 tableIndex int.Parse(splitString[1]); side int.Parse(splitString[2]);

欧阳地创编

=

= =

欧阳地创编

gameTable[tableIndex].gamePlayer[side].started = true;

if (side == 0) {

anotherSide = 1; sendString = \"Message,黑方已准备。\";

} else {

anotherSide = 0; sendString = \"Message,白方已准备。\";

}

service.SendToBoth(gameTable[tableIndex], sendString);

if

(gameTable[tableIndex].gamePlayer[anotherSide].started == true)

{

service.SendToBoth(gameTable[tableIndex], \"Start,游戏开始。\");

} break;

case \"NotReady\": tableIndex int.Parse(splitString[1]); side int.Parse(splitString[2]);

= =

gameTable[tableIndex].gamePlayer[side].started = false;

欧阳地创编

欧阳地创编

if (side == 0) {

sendString = \"Message,黑方取消准备。\";

} else {

sendString = \"Message,白方取消准备。\";

}

service.SendToBoth(gameTable[tableIndex], sendString);

//gameTable[tableIndex].StartTimer(); break;

case \"UnsetDot\":

//格式:UnsetDot,桌号,座位号,行,列,颜色

//消去客户单击的棋子 tableIndex int.Parse(splitString[1]); side int.Parse(splitString[2]); int int.Parse(splitString[3]); int int.Parse(splitString[4]); int int.Parse(splitString[5]);

xi xj color

= = = = =

gameTable[tableIndex].UnsetDot(xi, xj, color); break;

欧阳地创编

欧阳地创编

case \"SetDot\":

//格式:SetDot,桌号,座位号,行,列

//消去客户单击的棋子 tableIndex int.Parse(splitString[1]); side int.Parse(splitString[2]);

= =

anotherSide = (side + 1) % 2;

service.SendToOne(gameTable[tableIndex].gamePlayer[anotherSide].user, receiveString);

gameTable[tableIndex].gamePlayer[anotherSide].pass = false;

break; case \"Pass\":

//格式:Pass,桌号,座位号 tableIndex int.Parse(splitString[1]); side int.Parse(splitString[2]);

= =

anotherSide = (side + 1) % 2;

gameTable[tableIndex].gamePlayer[side].pass true;

=

if

(gameTable[tableIndex].gamePlayer[anotherSide].pass)

{

//双方都pass,棋局结束

service.SendToBoth(gameTable[tableIndex],

欧阳地创编

欧阳地创编

\"GameOver\");

gameTable[tableIndex].gamePlayer[side].pass false;

=

gameTable[tableIndex].gamePlayer[anotherSide].pass = false;

gameTable[tableIndex].gamePlayer[side].started = false;

gameTable[tableIndex].gamePlayer[anotherSide].started = false;

} else {

service.SendToOne(gameTable[tableIndex].gamePlayer[anotherSide].user, receiveString); } break; case \"Lose\":

//格式:Lose,桌号,座位号 tableIndex int.Parse(splitString[1]); side int.Parse(splitString[2]);

= =

anotherSide = (side + 1) % 2;

service.SendToOne(gameTable[tableIndex].gamePlayer[anotherSide].user, receiveString);

gameTable[tableIndex].gamePlayer[side].pass false;

欧阳地创编

=

欧阳地创编

gameTable[tableIndex].gamePlayer[anotherSide].pass = false;

gameTable[tableIndex].gamePlayer[side].started = false;

gameTable[tableIndex].gamePlayer[anotherSide].started = false;

break; default:

service.SendToAll(userList, \"什么意思啊:\" + receiveString);

break; } }

userList.Remove(user); client.Close();

service.SetListBox(string.Format(\"有一个退出,剩余连接用户数:{0}\ }

// 循环检测该用户是否坐到某游戏桌上,如果是,将其从游戏桌上移除,并终止该桌游戏

private void RemoveClientfromPlayer(User user) {

for (int i = 0; i < gameTable.Length; i++)

{

for (int j = 0; j < 2; j++) {

if

(gameTable[i].gamePlayer[j].user != null)

欧阳地创编

欧阳地创编

{

//判断是否同一个对象 if

(gameTable[i].gamePlayer[j].user == user) {

StopPlayer(i, j); return; } } } } }

//停止第i桌游戏

private void StopPlayer(int i, int j) {

gameTable[i].gamePlayer[j].someone = false;

gameTable[i].gamePlayer[j].started = false;

gameTable[i].gamePlayer[j].grade = 0; int otherSide = (j + 1) % 2; if

(gameTable[i].gamePlayer[otherSide].someone true)

{

gameTable[i].gamePlayer[otherSide].started false;

gameTable[i].gamePlayer[otherSide].grade = 0; if

(gameTable[i].gamePlayer[otherSide].user.client.C

欧阳地创编

==

=

欧阳地创编

onnected == true) {

//发送格式:Lost,座位号,用户名

service.SendToOne(gameTable[i].gamePlayer[otherSide].user,

string.Format(\"Lost,{0},{1}\

j,

gameTable[i].gamePlayer[j].user.userName)); } } }

//获取每桌是否有人的字符串,每座用一位表示,0表示无人,1表示有人

private string GetOnlineString() {

string str = \"\";

for (int i = 0; i < gameTable.Length; i++)

{

for (int j = 0; j < 2; j++) {

str += gameTable[i].gamePlayer[j].someone == true ? \"1\" : \"0\";

} }

return str; }

//关闭窗体前触发的事件

欧阳地创编

欧阳地创编

private

FormDDServer_FormClosing(object FormClosingEventArgs e) {

void sender,

//未单击开始服务就直接退出时,myListener为null

if (myListener != null) {

buttonStop_Click(null, null); } } } }

//---------------Service.cs-------------------// using System;

using System.Collections.Generic; using System.Text;

using System.Windows.Forms; using System.Net.Sockets; using System.IO; namespace GameServer {

class Service {

private ListBox listbox; //用于线程间互操作

private delegate SetListBoxCallback(string str); private setListBoxCallback;

欧阳地创编

void

SetListBoxCallback

欧阳地创编

public Service(ListBox listbox) {

this.listbox = listbox; setListBoxCallback SetListBoxCallback(SetListBox); }

public void SetListBox(string str) {

//比较调用SetListBox方法的线程和创建listBox1的线程是否同一个线程

//如果不是,则listBox1的InvokeRequired为true

if (listbox.InvokeRequired) {

//结果为true,则通过代理执行else中的代码,并传入需要的参数

listbox.Invoke(setListBoxCallback, str);

} else {

//结果为false,直接执行 listbox.Items.Add(str); listbox.SelectedIndex listbox.Items.Count - 1;

listbox.ClearSelected(); } }

public void SendToOne(User user, string str) {

try

欧阳地创编

= new

=

欧阳地创编

{

user.sw.WriteLine(str); user.sw.Flush();

SetListBox(string.Format(\"向{0}发送{1}\ } catch {

SetListBox(string.Format(\"向{0}发送信息失败\ } }

public void SendToBoth(GameTable gameTable, string str) {

for (int i = 0; i < 2; i++) {

if

(gameTable.gamePlayer[i].someone == true) {

SendToOne(gameTable.gamePlayer[i].user, str); } } }

public void SendToAll(System.Collections.Generic.List userList, string str) {

for (int i = 0; i < userList.Count; i++) {

欧阳地创编

欧阳地创编

SendToOne(userList[i], str); } } } }

//---------------Program.cs--------------// using System;

using System.Collections.Generic; using System.Windows.Forms; namespace GameServer {

static class Program {

///

/// The main entry point for the application. ///

[STAThread]

static void Main() {

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new FormServer()); } } }

结语

本游戏软件启发于陈春丽面向对象编程课程,许多程

欧阳地创编

欧阳地创编

序功能设计都源于陈老师的启发,在此,感谢陈春丽老师的大力支持。

时间:2021.03.04

创作:欧阳地 欧阳地创编

因篇幅问题不能全部显示,请点此查看更多更全内容