diff --git a/Box.cs b/Box.cs new file mode 100644 index 0000000..4fe5525 --- /dev/null +++ b/Box.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace TicTacToe +{ + public class Box + { + public Action Pressed; + public int Index; + public bool BotOwned = false; + private Button _button; + public bool Filled = false; + + public Box(Button button, int index) + { + _button = button; + Index = index; + button.Click += Clicked; + _button.Text = ""; + } + + private void Clicked(object sender, EventArgs e) + { + Pressed.Invoke(Index); + } + + public void Destroy() + { + _button.Text = ""; + _button.Click -= Clicked; + } + + public void SetEnabled(bool value) + { + _button.Enabled = value; + } + + public void PlayerClaim(bool bot) + { + Filled = true; + BotOwned = bot; + if (bot) + { + _button.Text = "O"; + } + else + { + _button.Text = "X"; + } + } + } +} diff --git a/Form1.Designer.cs b/Form1.Designer.cs index 7acc2af..e411dd1 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -28,12 +28,226 @@ /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; + menuStrip1 = new MenuStrip(); + fileToolStripMenuItem = new ToolStripMenuItem(); + newGameToolStripMenuItem = new ToolStripMenuItem(); + exitToolStripMenuItem = new ToolStripMenuItem(); + helpToolStripMenuItem = new ToolStripMenuItem(); + aboutToolStripMenuItem = new ToolStripMenuItem(); + lbl_wins = new Label(); + grid_7 = new Button(); + grid_4 = new Button(); + grid_1 = new Button(); + grid_2 = new Button(); + grid_5 = new Button(); + grid_8 = new Button(); + grid_0 = new Button(); + grid_3 = new Button(); + grid_6 = new Button(); + lbl_loses = new Label(); + menuStrip1.SuspendLayout(); + SuspendLayout(); + // + // menuStrip1 + // + menuStrip1.ImageScalingSize = new Size(24, 24); + menuStrip1.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem, helpToolStripMenuItem }); + menuStrip1.Location = new Point(0, 0); + menuStrip1.Name = "menuStrip1"; + menuStrip1.Size = new Size(800, 33); + menuStrip1.TabIndex = 3; + menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { newGameToolStripMenuItem, exitToolStripMenuItem }); + fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + fileToolStripMenuItem.Size = new Size(54, 29); + fileToolStripMenuItem.Text = "File"; + // + // newGameToolStripMenuItem + // + newGameToolStripMenuItem.Name = "newGameToolStripMenuItem"; + newGameToolStripMenuItem.Size = new Size(270, 34); + newGameToolStripMenuItem.Text = "New game"; + // + // exitToolStripMenuItem + // + exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + exitToolStripMenuItem.Size = new Size(270, 34); + exitToolStripMenuItem.Text = "Exit"; + // + // helpToolStripMenuItem + // + helpToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { aboutToolStripMenuItem }); + helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + helpToolStripMenuItem.Size = new Size(65, 29); + helpToolStripMenuItem.Text = "Help"; + // + // aboutToolStripMenuItem + // + aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + aboutToolStripMenuItem.Size = new Size(164, 34); + aboutToolStripMenuItem.Text = "About"; + // + // lbl_wins + // + lbl_wins.AutoSize = true; + lbl_wins.Location = new Point(337, 44); + lbl_wins.Name = "lbl_wins"; + lbl_wins.Size = new Size(131, 25); + lbl_wins.TabIndex = 4; + lbl_wins.Text = "Antal Vinster: 0"; + // + // grid_7 + // + grid_7.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_7.Location = new Point(368, 260); + grid_7.Name = "grid_7"; + grid_7.Size = new Size(64, 64); + grid_7.TabIndex = 5; + grid_7.Text = "O"; + grid_7.UseVisualStyleBackColor = true; + // + // grid_4 + // + grid_4.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_4.Location = new Point(368, 190); + grid_4.Name = "grid_4"; + grid_4.Size = new Size(64, 64); + grid_4.TabIndex = 6; + grid_4.Text = "O"; + grid_4.UseVisualStyleBackColor = true; + // + // grid_1 + // + grid_1.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_1.Location = new Point(368, 120); + grid_1.Name = "grid_1"; + grid_1.Size = new Size(64, 64); + grid_1.TabIndex = 7; + grid_1.Text = "X"; + grid_1.UseVisualStyleBackColor = true; + // + // grid_2 + // + grid_2.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_2.Location = new Point(438, 120); + grid_2.Name = "grid_2"; + grid_2.Size = new Size(64, 64); + grid_2.TabIndex = 8; + grid_2.Text = "O"; + grid_2.UseVisualStyleBackColor = true; + // + // grid_5 + // + grid_5.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_5.Location = new Point(438, 190); + grid_5.Name = "grid_5"; + grid_5.Size = new Size(64, 64); + grid_5.TabIndex = 9; + grid_5.Text = "O"; + grid_5.UseVisualStyleBackColor = true; + // + // grid_8 + // + grid_8.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_8.Location = new Point(438, 260); + grid_8.Name = "grid_8"; + grid_8.Size = new Size(64, 64); + grid_8.TabIndex = 10; + grid_8.Text = "O"; + grid_8.UseVisualStyleBackColor = true; + // + // grid_0 + // + grid_0.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_0.Location = new Point(298, 120); + grid_0.Name = "grid_0"; + grid_0.Size = new Size(64, 64); + grid_0.TabIndex = 13; + grid_0.Text = "O"; + grid_0.UseVisualStyleBackColor = true; + // + // grid_3 + // + grid_3.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_3.Location = new Point(298, 190); + grid_3.Name = "grid_3"; + grid_3.Size = new Size(64, 64); + grid_3.TabIndex = 12; + grid_3.Text = "O"; + grid_3.UseVisualStyleBackColor = true; + // + // grid_6 + // + grid_6.Font = new Font("Segoe UI", 22F, FontStyle.Bold); + grid_6.Location = new Point(298, 260); + grid_6.Name = "grid_6"; + grid_6.Size = new Size(64, 64); + grid_6.TabIndex = 11; + grid_6.Text = "O"; + grid_6.UseVisualStyleBackColor = true; + // + // lbl_loses + // + lbl_loses.AutoSize = true; + lbl_loses.Location = new Point(337, 69); + lbl_loses.Name = "lbl_loses"; + lbl_loses.Size = new Size(146, 25); + lbl_loses.TabIndex = 14; + lbl_loses.Text = "Antal Förluster: 0"; + // + // Form1 + // + AutoScaleDimensions = new SizeF(10F, 25F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(lbl_loses); + Controls.Add(grid_0); + Controls.Add(grid_3); + Controls.Add(grid_6); + Controls.Add(grid_8); + Controls.Add(grid_5); + Controls.Add(grid_2); + Controls.Add(grid_1); + Controls.Add(grid_4); + Controls.Add(grid_7); + Controls.Add(lbl_wins); + Controls.Add(menuStrip1); + MainMenuStrip = menuStrip1; + Name = "Form1"; + Text = "Form1"; + menuStrip1.ResumeLayout(false); + menuStrip1.PerformLayout(); + ResumeLayout(false); + PerformLayout(); } #endregion + + private Button btn_restart; + private MenuStrip menuStrip1; + private ToolStripMenuItem fileToolStripMenuItem; + private ToolStripMenuItem helpToolStripMenuItem; + private Label label1; + private ToolStripMenuItem aboutToolStripMenuItem; + private Button button3; + private Button button4; + private Button button5; + private Button button8; + public Button grid_7; + public Button grid_5; + public Button grid_8; + public Button grid_3; + public Button grid_6; + public Button grid_4; + public Button grid_0; + public Button grid_1; + public Button grid_2; + public Label lbl_wins; + public ToolStripMenuItem newGameToolStripMenuItem; + public Label lbl_loses; + public ToolStripMenuItem exitToolStripMenuItem; } } diff --git a/Form1.resx b/Form1.resx index 1af7de1..b48baf1 100644 --- a/Form1.resx +++ b/Form1.resx @@ -1,17 +1,17 @@  - @@ -117,4 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file diff --git a/Game.cs b/Game.cs new file mode 100644 index 0000000..dd8b40a --- /dev/null +++ b/Game.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Media; +using System.Text; +using System.Threading.Tasks; +using System.Threading.Tasks.Dataflow; + +namespace TicTacToe +{ + public class Game + { + Form1 form; + Box[] boxes = new Box[9]; + bool BotRound = false; + + public Game() + { + form = Program.form; + boxes[0] = new Box(form.grid_0, 0); boxes[0].Pressed += ButtonClicked; + boxes[1] = new Box(form.grid_1, 1); boxes[1].Pressed += ButtonClicked; + boxes[2] = new Box(form.grid_2, 2); boxes[2].Pressed += ButtonClicked; + boxes[3] = new Box(form.grid_3, 3); boxes[3].Pressed += ButtonClicked; + boxes[4] = new Box(form.grid_4, 4); boxes[4].Pressed += ButtonClicked; + boxes[5] = new Box(form.grid_5, 5); boxes[5].Pressed += ButtonClicked; + boxes[6] = new Box(form.grid_6, 6); boxes[6].Pressed += ButtonClicked; + boxes[7] = new Box(form.grid_7, 7); boxes[7].Pressed += ButtonClicked; + boxes[8] = new Box(form.grid_8, 8); boxes[8].Pressed += ButtonClicked; + } + + public void Start() + { + Round(); + } + + public void ButtonClicked(int index) + { + Box box = boxes[index]; + if (box.Filled) return; + box.PlayerClaim(BotRound); + RoundEnded(); + } + + public void Round() + { + if (BotRound) + { + BotTurn(); + } + else + { + PlayerTurn(); + } + } + + public void BotTurn() + { + SetInputEnabled(false); + + Random random = new Random(); + Box box; + bool[] boxCache = new bool[9]; + + while (true) + { + int randomIndex = random.Next(0, 8); + box = boxes[randomIndex]; + boxCache[randomIndex] = true; + if (!box.Filled) + { + break; + } + } + + box.PlayerClaim(true); + + RoundEnded(); + } + + public bool CheckWins() + { + int[][] lines = + { + new[] {0, 1, 2}, + new[] {3, 4, 5}, + new[] {6, 7, 8}, + new[] {0, 3, 6}, + new[] {1, 4, 7}, + new[] {2, 5, 8}, + new[] {0, 4, 8}, + new[] {2, 4, 6} + }; + + foreach (var line in lines) + { + if (!boxes[line[0]].Filled || !boxes[line[1]].Filled || !boxes[line[2]].Filled) + continue; + + if (boxes[line[0]].BotOwned == BotRound && + boxes[line[1]].BotOwned == BotRound && + boxes[line[2]].BotOwned == BotRound) + { + return true; + } + } + + return false; + } + + public void PlayerTurn() + { + SetInputEnabled(true); + } + + public void CheckWin() + { + + } + + public void RoundEnded() + { + if (CheckWins()) + { + if (BotRound) + { + MessageBox.Show("You lost"); + Program.AddLose(); + } + else + { + MessageBox.Show("You won"); + Program.AddWin(); + } + return; + } + + BotRound = !BotRound; + + if (IsAllBoxesFilled()) + { + MessageBox.Show("Tie"); + } + else + { + Round(); + } + } + + public bool IsAllBoxesFilled() + { + foreach (Box box in boxes) + { + if (!box.Filled) + return false; + } + + return true; + } + + public void SetInputEnabled(bool value) + { + foreach (Box box in boxes) + { + box.SetEnabled(value); + } + } + + public void Destroy() + { + foreach (Box box in boxes) + { + box.Destroy(); + } + } + } +} diff --git a/Program.cs b/Program.cs index f0c5897..77c1177 100644 --- a/Program.cs +++ b/Program.cs @@ -1,17 +1,44 @@ namespace TicTacToe { - internal static class Program + public static class Program { - /// - /// The main entry point for the application. - /// - [STAThread] + public static Form1 form = new Form1(); + static Game game; + static int wins = 0; + static int loses = 0; + static void Main() { - // To customize application configuration such as set high DPI settings or default font, - // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new Form1()); + game = new Game(); + game.Start(); + form.newGameToolStripMenuItem.Click += NewGame; + form.exitToolStripMenuItem.Click += Exit; + Application.Run(form); + } + + static void NewGame(object sender, EventArgs e) + { + game.Destroy(); + game = new Game(); + game.Start(); + } + + static void Exit(object sender, EventArgs e) + { + Application.Exit(); + } + + public static void AddLose() + { + loses += 1; + form.lbl_loses.Text = "Antal Förluster: " + loses.ToString(); + } + + public static void AddWin() + { + wins += 1; + form.lbl_wins.Text = "Antal Vinster: " + wins.ToString(); } } } \ No newline at end of file