📄 mainform.cs
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Media;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Threading;
namespace TicTacToe
{
public partial class MainForm : Form
{
private const int PEN_WIDTH = 6;
private const int GRID_WIDTH = 4;
private const int MARGIN_WIDTH = 6;
private const String cheatCode = "snyd";
private readonly String defaultStatusMessage = Properties.Resources.StatusReady;
private readonly String bluesTurnStatusMessage = Properties.Resources.StatusBluesTurn;
private readonly String redsTurnStatusMessage = Properties.Resources.StatusRedsTurn;
private readonly String yourTurnStatusMessage = Properties.Resources.StatusYourTurn;
private readonly String gameOverStatusMessage = Properties.Resources.GameOver;
private int boardWidth;
private int boardHeight;
private int cellWidth;
private int cellHeight;
private int y0;
private Image blueSmileyImage;
private Image redSmileyImage;
private Image yellowSmileyImage;
private DateTime startTime;
private bool cheatActivated = false;
private StringBuilder keypressBuffer = new StringBuilder(cheatCode.Length);
private SoundPlayer winnerSound = new SoundPlayer(Properties.Resources.tada);
private SoundPlayer invalidSound = new SoundPlayer(Properties.Resources.HONK);
private ITicTacToe gameEngine = new GameEngine();
public MainForm()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
InitializeComponent();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show(Properties.Resources.ExitMessage, Properties.Resources.ExitDialogTitle);
Close();
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutBox dlg = new AboutBox();
dlg.ShowDialog();
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
Graphics g = Graphics.FromHwnd(this.Handle);
// Erase client area
g.Clear(Color.White);
DrawGrid(g);
DrawCells(g);
}
private void DrawGrid(Graphics g)
{
int x = boardWidth / 3;
int y = y0;
Pen pen = new Pen(Color.Black, GRID_WIDTH);
g.DrawLine(pen, x, y, x, y + boardHeight);
x += x;
g.DrawLine(pen, x, y, x, y + boardHeight);
y = y0 + boardHeight / 3;
g.DrawLine(pen, 0, y, boardWidth, y);
y += boardHeight / 3;
g.DrawLine(pen, 0, y, boardWidth, y);
}
private void DrawCells(Graphics g)
{
int x, y, index;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
index = 0;
for (int j = 0; j < gameEngine.Rows; j++)
{
for (int i = 0; i < gameEngine.Columns; i++)
{
x = i * (cellWidth + GRID_WIDTH) + MARGIN_WIDTH;
y = y0 + j * (cellHeight + GRID_WIDTH) + MARGIN_WIDTH;
if (gameEngine.GetCellState(index) == CellState.Cross)
DrawCross(g, x, y, cellWidth - 2 * MARGIN_WIDTH, cellHeight - 2 * MARGIN_WIDTH);
else if (gameEngine.GetCellState(index) == CellState.Circle)
DrawCircle(g, x, y, cellWidth - 2 * MARGIN_WIDTH, cellHeight - 2 * MARGIN_WIDTH);
index++;
}
}
}
private void DrawCross(Graphics g, int x, int y, int width, int height)
{
if (smileysToolStripMenuItem.Checked)
{
g.DrawImage(blueSmileyImage, x, y, width, height);
}
else
{
Pen pen = new Pen(Color.Blue, PEN_WIDTH);
pen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
g.DrawLine(pen, x, y, x + width, y + height);
g.DrawLine(pen, x, y + height, x + width, y);
}
}
private void DrawCircle(Graphics g, int x, int y, int width, int height)
{
if (smileysToolStripMenuItem.Checked)
{
g.DrawImage(redSmileyImage, x, y, width, height);
}
else
{
Pen pen = new Pen(Color.Red, PEN_WIDTH);
g.DrawEllipse(pen, x, y, width, height);
}
}
private void InitSize()
{
y0 = MainMenuStrip.Height;
if (toolbarStrip.Visible)
y0 += toolbarStrip.Height;
boardWidth = this.ClientSize.Width;
boardHeight = this.ClientSize.Height - y0;
if (statusBarStrip.Visible)
boardHeight -= statusBarStrip.Height;
cellWidth = (boardWidth - 2 * GRID_WIDTH) / 3;
cellHeight = (boardHeight - 2 * GRID_WIDTH) / 3;
}
private void MainForm_Resize(object sender, EventArgs e)
{
InitSize();
Invalidate();
}
private void MainForm_MouseClick(object sender, MouseEventArgs e)
{
// Map mouse click position to cell index
int col = 3 * e.X / boardWidth;
int row = 3 * (e.Y - y0) / boardHeight;
int index = row * gameEngine.Columns + col;
if (cheatActivated || gameEngine.GetCellState(index) == CellState.Empty)
{
gameEngine.OccupyCell(index);
if (!twoPlayerToolStripMenuItem.Checked)
gameEngine.MakeComputerMove();
}
else
invalidSound.Play();
Graphics g = Graphics.FromHwnd(this.Handle);
DrawCells(g);
if (gameEngine.IsGameOver())
{
Image winnerSymbol = null;
String msg;
timerGame.Stop();
if (gameEngine.GetWinner() == CellState.Cross)
{
winnerSound.Play();
winnerSymbol = blueSmileyImage;
msg = Properties.Resources.BlueWins;
}
else if (gameEngine.GetWinner() == CellState.Circle)
{
winnerSound.Play();
winnerSymbol = redSmileyImage;
msg = Properties.Resources.RedWins;
}
else
{
// It's a draw
SoundPlayer drawSound = new SoundPlayer(Properties.Resources.TAKEMY);
drawSound.Play();
winnerSymbol = yellowSmileyImage;
msg = Properties.Resources.NoWinner;
}
GameOverForm dlg = new GameOverForm();
dlg.SetResult(winnerSymbol, msg);
dlg.ShowDialog();
StartNewGame();
}
}
private void StartNewGame()
{
gameEngine.NewGame();
Invalidate();
startTime = DateTime.Now;
timerGame.Start();
}
private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
{
StartNewGame();
}
private void MainForm_Load(object sender, EventArgs e)
{
// Load and apply user settings
if (Properties.Settings.Default.Level.Equals("Easy"))
easyToolStripMenuItem_Click(null, null);
if (Properties.Settings.Default.ShowSmileys)
{
smileysToolStripMenuItem.Checked = true;
smileysToolStripMenuItem_Click(null, null);
}
if (Properties.Settings.Default.Language.Equals("da-DK"))
{
englishToolStripMenuItem.Checked = false;
danishToolStripMenuItem.Checked = true;
}
this.Size = Properties.Settings.Default.FormSize;
blueSmileyImage = Properties.Resources.BlueSmiley;
redSmileyImage = Properties.Resources.RedSmiley;
yellowSmileyImage = Properties.Resources.SadSmiley;
InitSize();
// Append Idle processing handler
Application.Idle += new System.EventHandler(OnIdle);
gameEngine.SetLevel(Level.Hard);
StartNewGame();
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.Level = hardToolStripMenuItem.Checked ? "Hard" : "Easy";
Properties.Settings.Default.ShowSmileys = smileysToolStripMenuItem.Checked;
Properties.Settings.Default.FormSize = this.Size;
Properties.Settings.Default.Save();
}
private void toolbarToolStripMenuItem_Click(object sender, EventArgs e)
{
toolbarStrip.Visible = toolbarToolStripMenuItem.Checked;
InitSize();
Invalidate();
}
private void statusBarToolStripMenuItem_Click(object sender, EventArgs e)
{
statusBarStrip.Visible = statusBarToolStripMenuItem.Checked;
InitSize();
Invalidate();
}
private void smileysToolStripMenuItem_Click(object sender, EventArgs e)
{
// Synchronize menubar and toolbar button state
toolStripButtonSmileys.Checked = smileysToolStripMenuItem.Checked;
Invalidate();
}
private void toolStripButtonNewGame_Click(object sender, EventArgs e)
{
newGameToolStripMenuItem_Click(sender, e);
}
// Called when the application is idle
private void OnIdle(object sender, EventArgs e)
{
// Update status bar info
String msg = defaultStatusMessage;
if (gameEngine != null)
{
if (gameEngine.IsGameOver())
{
msg = gameOverStatusMessage;
}
else
{
if (gameEngine.IsCrossesTurn())
msg = twoPlayerToolStripMenuItem.Checked ? bluesTurnStatusMessage : yourTurnStatusMessage;
else
msg = redsTurnStatusMessage;
}
}
this.statusBarStrip.Items[0].Text = msg;
}
private void timerGame_Tick(object sender, EventArgs e)
{
// Update time elapsed pane in status bar
DateTime currentTime = DateTime.Now;
TimeSpan timeSpan = currentTime - startTime;
currentTime = new DateTime(timeSpan.Ticks);
this.statusBarStrip.Items[1].Text = currentTime.ToLongTimeString();
}
private void toolStripButtonSmileys_Click(object sender, EventArgs e)
{
// Synchronize menubar and toolbar button state
smileysToolStripMenuItem.Checked = toolStripButtonSmileys.Checked;
Invalidate();
}
private void MainForm_KeyPress(object sender, KeyPressEventArgs e)
{
if (cheatActivated)
return;
if (cheatCode.IndexOf(e.KeyChar) == -1 || keypressBuffer.Length > cheatCode.Length)
{
keypressBuffer.Remove(0, keypressBuffer.Length);
}
else
{
keypressBuffer.Append(e.KeyChar);
if (keypressBuffer.ToString().Equals(cheatCode))
{
// Cheat code entered!
cheatActivated = true;
this.Text = this.Text + " (" + Properties.Resources.CheatMode + ")";
keypressBuffer.Remove(0, keypressBuffer.Length);
}
}
}
private void easyToolStripMenuItem_Click(object sender, EventArgs e)
{
easyToolStripMenuItem.Checked = true;
hardToolStripMenuItem.Checked = false;
gameEngine.SetLevel(Level.Easy);
}
private void hardToolStripMenuItem_Click(object sender, EventArgs e)
{
hardToolStripMenuItem.Checked = true;
easyToolStripMenuItem.Checked = false;
gameEngine.SetLevel(Level.Hard);
}
private void englishToolStripMenuItem_Click(object sender, EventArgs e)
{
englishToolStripMenuItem.Checked = true;
danishToolStripMenuItem.Checked = false;
Properties.Settings.Default.Language = "en-US";
Application.Restart();
}
private void danishToolStripMenuItem_Click(object sender, EventArgs e)
{
danishToolStripMenuItem.Checked = true;
englishToolStripMenuItem.Checked = false;
Properties.Settings.Default.Language = "da-DK";
Application.Restart();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -