-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPlayer.cs
161 lines (150 loc) · 5.12 KB
/
Player.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
namespace TicTacToe {
public interface IPlayer {
Texture2D texture { get; set; }
Board Play(Board board);
void WinMsg(SpriteBatch sb, Vector2 pos);
}
public abstract class BasePlayer {
public enum Type {
None,
Human,
AI
};
public Type _type;
public static IPlayer BuildPlayer(Type type, BaseAI.Difficulty difficulty = BaseAI.Difficulty.Normal) {
BasePlayer p;
switch (type) {
case Type.None:
return null;
case Type.Human:
p = new HumanPlayer();
p._type = Type.Human;
return (IPlayer)p;
case Type.AI:
p = (BasePlayer)BaseAI.BuildPlayer(difficulty);
p._type = Type.AI;
return (IPlayer)p;
default:
break;
}
Debug.Assert(false, "Thats not a player type");
return null;
}
public Texture2D _texture;
public Texture2D texture {
get {
return _texture;
}
set {
_texture = value;
}
}
}
public class HumanPlayer : BasePlayer, IPlayer {
Board IPlayer.Play(Board board) {
if (board._cell_clicked != null) {
board.SetMove(board._cell_clicked.Item1,
board._cell_clicked.Item2);
board._cell_clicked = null;
}
return board;
}
void IPlayer.WinMsg(SpriteBatch sb, Vector2 pos) {
Primitives.DrawText(sb, pos, "Congratulations! You Won!", Color.White);
}
}
public abstract class BaseAI : BasePlayer {
public enum Difficulty {
Hard,
Normal,
Easy
};
public static Random _random;
static BaseAI() {
_random = new Random();
}
public static IPlayer BuildPlayer(Difficulty difficulty) {
switch (difficulty) {
case Difficulty.Hard:
return new HardAI();
case Difficulty.Normal:
return new NormalAI();
case Difficulty.Easy:
return new EasyAI();
default:
break;
}
Debug.Assert(false, "No patric, DarkSouls is not a difficulty!");
return null;
}
public void WinMsg(SpriteBatch sb, Vector2 pos) {
Primitives.DrawText(sb, pos, "CPU Wins! All hail our new robot overlords.", Color.White);
}
}
public class HardAI : BaseAI, IPlayer {
Board IPlayer.Play(Board board) {
Primitives.PlaySound();
Minmax mm = new Minmax(board, this);
if (mm._wins.Count > 0) {
return mm._wins.ElementAt(_random.Next(mm._wins.Count));
}
if (mm._draws.Count > 0) {
return mm._draws.ElementAt(_random.Next(mm._draws.Count));
}
if (mm._loss.Count > 0) {
return mm._loss.ElementAt(_random.Next(mm._loss.Count));
}
Debug.Assert(false, "The only move is not to play <o>!");
return null;
}
}
public class NormalAI : BaseAI, IPlayer {
Board IPlayer.Play(Board board) {
Primitives.PlaySound();
if (_random.Next(2) > 0) {
List<Board> b = board.Branches();
return b.ElementAt(_random.Next(b.Count));
}
else {
Minmax mm = new Minmax(board, this);
if (mm._wins.Count > 0) {
return mm._wins.ElementAt(_random.Next(mm._wins.Count));
}
if (mm._draws.Count > 0) {
return mm._draws.ElementAt(_random.Next(mm._draws.Count));
}
if (mm._loss.Count > 0) {
return mm._loss.ElementAt(_random.Next(mm._loss.Count));
}
Debug.Assert(false, "The only move is not to play <o>!");
return null;
}
}
}
public class EasyAI : BaseAI, IPlayer {
Board IPlayer.Play(Board board) {
Primitives.PlaySound();
Minmax mm = new Minmax(board, this);
if (mm._loss.Count > 0) {
return mm._loss.ElementAt(_random.Next(mm._loss.Count));
}
if (mm._draws.Count > 0) {
return mm._draws.ElementAt(_random.Next(mm._draws.Count));
}
if (mm._wins.Count > 0) {
return mm._wins.ElementAt(_random.Next(mm._wins.Count));
}
Debug.Assert(false, "The only move is not to play <o>!");
return null;
}
}
}