├── .gitattributes
├── .gitignore
├── BattleshipModellingPractice.sln
├── BattleshipModellingPractice
├── App.config
├── BattleshipModellingPractice.csproj
├── Enums.cs
├── Extensions
│ ├── EnumExtensions.cs
│ └── PanelExtensions.cs
├── Objects
│ ├── Boards
│ │ ├── Coordinates.cs
│ │ ├── FiringBoard.cs
│ │ ├── GameBoard.cs
│ │ └── Panel.cs
│ ├── Games
│ │ └── Game.cs
│ ├── Player.cs
│ └── Ships
│ │ ├── Battleship.cs
│ │ ├── Carrier.cs
│ │ ├── Cruiser.cs
│ │ ├── Destroyer.cs
│ │ ├── Ship.cs
│ │ └── Submarine.cs
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | [Xx]64/
19 | [Xx]86/
20 | [Bb]uild/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 |
85 | # Visual Studio profiler
86 | *.psess
87 | *.vsp
88 | *.vspx
89 | *.sap
90 |
91 | # TFS 2012 Local Workspace
92 | $tf/
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 | *.DotSettings.user
101 |
102 | # JustCode is a .NET coding add-in
103 | .JustCode
104 |
105 | # TeamCity is a build add-in
106 | _TeamCity*
107 |
108 | # DotCover is a Code Coverage Tool
109 | *.dotCover
110 |
111 | # NCrunch
112 | _NCrunch_*
113 | .*crunch*.local.xml
114 | nCrunchTemp_*
115 |
116 | # MightyMoose
117 | *.mm.*
118 | AutoTest.Net/
119 |
120 | # Web workbench (sass)
121 | .sass-cache/
122 |
123 | # Installshield output folder
124 | [Ee]xpress/
125 |
126 | # DocProject is a documentation generator add-in
127 | DocProject/buildhelp/
128 | DocProject/Help/*.HxT
129 | DocProject/Help/*.HxC
130 | DocProject/Help/*.hhc
131 | DocProject/Help/*.hhk
132 | DocProject/Help/*.hhp
133 | DocProject/Help/Html2
134 | DocProject/Help/html
135 |
136 | # Click-Once directory
137 | publish/
138 |
139 | # Publish Web Output
140 | *.[Pp]ublish.xml
141 | *.azurePubxml
142 |
143 | # TODO: Un-comment the next line if you do not want to checkin
144 | # your web deploy settings because they may include unencrypted
145 | # passwords
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # NuGet Packages
150 | *.nupkg
151 | # The packages folder can be ignored because of Package Restore
152 | **/packages/*
153 | # except build/, which is used as an MSBuild target.
154 | !**/packages/build/
155 | # Uncomment if necessary however generally it will be regenerated when needed
156 | #!**/packages/repositories.config
157 | # NuGet v3's project.json files produces more ignoreable files
158 | *.nuget.props
159 | *.nuget.targets
160 |
161 | # Microsoft Azure Build Output
162 | csx/
163 | *.build.csdef
164 |
165 | # Microsoft Azure Emulator
166 | ecf/
167 | rcf/
168 |
169 | # Microsoft Azure ApplicationInsights config file
170 | ApplicationInsights.config
171 |
172 | # Windows Store app package directory
173 | AppPackages/
174 | BundleArtifacts/
175 |
176 | # Visual Studio cache files
177 | # files ending in .cache can be ignored
178 | *.[Cc]ache
179 | # but keep track of directories ending in .cache
180 | !*.[Cc]ache/
181 |
182 | # Others
183 | ClientBin/
184 | [Ss]tyle[Cc]op.*
185 | ~$*
186 | *~
187 | *.dbmdl
188 | *.dbproj.schemaview
189 | *.pfx
190 | *.publishsettings
191 | node_modules/
192 | orleans.codegen.cs
193 |
194 | # RIA/Silverlight projects
195 | Generated_Code/
196 |
197 | # Backup & report files from converting an old project file
198 | # to a newer Visual Studio version. Backup files are not needed,
199 | # because we have git ;-)
200 | _UpgradeReport_Files/
201 | Backup*/
202 | UpgradeLog*.XML
203 | UpgradeLog*.htm
204 |
205 | # SQL Server files
206 | *.mdf
207 | *.ldf
208 |
209 | # Business Intelligence projects
210 | *.rdl.data
211 | *.bim.layout
212 | *.bim_*.settings
213 |
214 | # Microsoft Fakes
215 | FakesAssemblies/
216 |
217 | # GhostDoc plugin setting file
218 | *.GhostDoc.xml
219 |
220 | # Node.js Tools for Visual Studio
221 | .ntvs_analysis.dat
222 |
223 | # Visual Studio 6 build log
224 | *.plg
225 |
226 | # Visual Studio 6 workspace options file
227 | *.opt
228 |
229 | # Visual Studio LightSwitch build output
230 | **/*.HTMLClient/GeneratedArtifacts
231 | **/*.DesktopClient/GeneratedArtifacts
232 | **/*.DesktopClient/ModelManifest.xml
233 | **/*.Server/GeneratedArtifacts
234 | **/*.Server/ModelManifest.xml
235 | _Pvt_Extensions
236 |
237 | # LightSwitch generated files
238 | GeneratedArtifacts/
239 | ModelManifest.xml
240 |
241 | # Paket dependency manager
242 | .paket/paket.exe
243 |
244 | # FAKE - F# Make
245 | .fake/
--------------------------------------------------------------------------------
/BattleshipModellingPractice.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BattleshipModellingPractice", "BattleshipModellingPractice\BattleshipModellingPractice.csproj", "{DC5A4B6F-FD2F-438C-8D0B-6CCD5F06E1DC}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {DC5A4B6F-FD2F-438C-8D0B-6CCD5F06E1DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {DC5A4B6F-FD2F-438C-8D0B-6CCD5F06E1DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {DC5A4B6F-FD2F-438C-8D0B-6CCD5F06E1DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {DC5A4B6F-FD2F-438C-8D0B-6CCD5F06E1DC}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/BattleshipModellingPractice.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {DC5A4B6F-FD2F-438C-8D0B-6CCD5F06E1DC}
8 | Exe
9 | Properties
10 | BattleshipModellingPractice
11 | BattleshipModellingPractice
12 | v4.6
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
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 |
75 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Enums.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace BattleshipModellingPractice
9 | {
10 | public enum OccupationType
11 | {
12 | [Description("o")]
13 | Empty,
14 |
15 | [Description("B")]
16 | Battleship,
17 |
18 | [Description("C")]
19 | Cruiser,
20 |
21 | [Description("D")]
22 | Destroyer,
23 |
24 | [Description("S")]
25 | Submarine,
26 |
27 | [Description("A")]
28 | Carrier,
29 |
30 | [Description("X")]
31 | Hit,
32 |
33 | [Description("M")]
34 | Miss
35 | }
36 |
37 | public enum ShotResult
38 | {
39 | Miss,
40 | Hit
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Extensions/EnumExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BattleshipModellingPractice.Extensions
8 | {
9 | public static class EnumExtensions
10 | {
11 | public static T GetAttributeOfType(this Enum enumVal) where T : System.Attribute
12 | {
13 | var type = enumVal.GetType();
14 | var memInfo = type.GetMember(enumVal.ToString());
15 | var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
16 | return (attributes.Length > 0) ? (T)attributes[0] : null;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Extensions/PanelExtensions.cs:
--------------------------------------------------------------------------------
1 | using BattleshipModellingPractice.Objects.Boards;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace BattleshipModellingPractice.Extensions
9 | {
10 | public static class PanelExtensions
11 | {
12 | public static Panel At(this List panels, int row, int column)
13 | {
14 | return panels.Where(x => x.Coordinates.Row == row && x.Coordinates.Column == column).First();
15 | }
16 |
17 | public static List Range(this List panels, int startRow, int startColumn, int endRow, int endColumn)
18 | {
19 | return panels.Where(x => x.Coordinates.Row >= startRow
20 | && x.Coordinates.Column >= startColumn
21 | && x.Coordinates.Row <= endRow
22 | && x.Coordinates.Column <= endColumn).ToList();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Boards/Coordinates.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BattleshipModellingPractice.Objects.Boards
8 | {
9 | public class Coordinates
10 | {
11 | public int Row { get; set; }
12 | public int Column { get; set; }
13 |
14 | public Coordinates(int row, int column)
15 | {
16 | Row = row;
17 | Column = column;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Boards/FiringBoard.cs:
--------------------------------------------------------------------------------
1 | using BattleshipModellingPractice.Extensions;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace BattleshipModellingPractice.Objects.Boards
9 | {
10 | ///
11 | /// Represents a collection of Panels to show where the player has fired shots, and whether those shots are hits or misses.
12 | ///
13 | public class FiringBoard : GameBoard
14 | {
15 | public List GetOpenRandomPanels()
16 | {
17 | return Panels.Where(x => x.OccupationType == OccupationType.Empty && x.IsRandomAvailable).Select(x=>x.Coordinates).ToList();
18 | }
19 |
20 | public List GetHitNeighbors()
21 | {
22 | List panels = new List();
23 | var hits = Panels.Where(x => x.OccupationType == OccupationType.Hit);
24 | foreach(var hit in hits)
25 | {
26 | panels.AddRange(GetNeighbors(hit.Coordinates).ToList());
27 | }
28 | return panels.Distinct().Where(x => x.OccupationType == OccupationType.Empty).Select(x => x.Coordinates).ToList();
29 | }
30 |
31 | public List GetNeighbors(Coordinates coordinates)
32 | {
33 | int row = coordinates.Row;
34 | int column = coordinates.Column;
35 | List panels = new List();
36 | if (column > 1)
37 | {
38 | panels.Add(Panels.At(row, column - 1));
39 | }
40 | if (row > 1)
41 | {
42 | panels.Add(Panels.At(row - 1, column));
43 | }
44 | if (row < 10)
45 | {
46 | panels.Add(Panels.At(row + 1, column));
47 | }
48 | if (column < 10)
49 | {
50 | panels.Add(Panels.At(row, column + 1));
51 | }
52 | return panels;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Boards/GameBoard.cs:
--------------------------------------------------------------------------------
1 | using BattleshipModellingPractice.Extensions;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace BattleshipModellingPractice.Objects.Boards
9 | {
10 | ///
11 | /// Represents a collection of Panels to provide a Player with their Game Board (e.g. where their ships are placed).
12 | ///
13 | public class GameBoard
14 | {
15 | public List Panels { get; set; }
16 |
17 | public GameBoard()
18 | {
19 | Panels = new List();
20 | for (int i = 1; i <= 10; i++)
21 | {
22 | for (int j = 1; j <= 10; j++)
23 | {
24 | Panels.Add(new Panel(i, j));
25 | }
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Boards/Panel.cs:
--------------------------------------------------------------------------------
1 | using BattleshipModellingPractice.Extensions;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace BattleshipModellingPractice.Objects.Boards
10 | {
11 | ///
12 | /// The basic class for this modelling practice. Represents a single square on the game board.
13 | ///
14 | public class Panel
15 | {
16 | public OccupationType OccupationType { get; set; }
17 | public Coordinates Coordinates { get; set; }
18 |
19 | public Panel(int row, int column)
20 | {
21 | Coordinates = new Coordinates(row, column);
22 | OccupationType = OccupationType.Empty;
23 | }
24 |
25 | public string Status
26 | {
27 | get
28 | {
29 | return OccupationType.GetAttributeOfType().Description;
30 | }
31 | }
32 |
33 | public bool IsOccupied
34 | {
35 | get
36 | {
37 | return OccupationType == OccupationType.Battleship
38 | || OccupationType == OccupationType.Destroyer
39 | || OccupationType == OccupationType.Cruiser
40 | || OccupationType == OccupationType.Submarine
41 | || OccupationType == OccupationType.Carrier;
42 | }
43 | }
44 |
45 | public bool IsRandomAvailable
46 | {
47 | get
48 | {
49 | return (Coordinates.Row % 2 == 0 && Coordinates.Column % 2 == 0)
50 | || (Coordinates.Row % 2 == 1 && Coordinates.Column % 2 == 1);
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Games/Game.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BattleshipModellingPractice.Objects.Games
8 | {
9 | public class Game
10 | {
11 | public Player Player1 { get; set; }
12 | public Player Player2 { get; set; }
13 |
14 | public Game()
15 | {
16 | Player1 = new Player("Amy");
17 | Player2 = new Player("Vince");
18 |
19 | Player1.PlaceShips();
20 | Player2.PlaceShips();
21 |
22 | Player1.OutputBoards();
23 | Player2.OutputBoards();
24 | }
25 |
26 | public void PlayRound()
27 | {
28 | //Each exchange of shots is called a Round.
29 | //One round = Player 1 fires a shot, then Player 2 fires a shot.
30 | var coordinates = Player1.FireShot();
31 | var result = Player2.ProcessShot(coordinates);
32 | Player1.ProcessShotResult(coordinates, result);
33 |
34 | if (!Player2.HasLost) //If player 2 already lost, we can't let them take another turn.
35 | {
36 | coordinates = Player2.FireShot();
37 | result = Player1.ProcessShot(coordinates);
38 | Player2.ProcessShotResult(coordinates, result);
39 | }
40 | }
41 |
42 | public void PlayToEnd()
43 | {
44 | while (!Player1.HasLost && !Player2.HasLost)
45 | {
46 | PlayRound();
47 | }
48 |
49 | Player1.OutputBoards();
50 | Player2.OutputBoards();
51 |
52 | if (Player1.HasLost)
53 | {
54 | Console.WriteLine(Player2.Name + " has won the game!");
55 | }
56 | else if (Player2.HasLost)
57 | {
58 | Console.WriteLine(Player1.Name + " has won the game!");
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Player.cs:
--------------------------------------------------------------------------------
1 | using BattleshipModellingPractice.Extensions;
2 | using BattleshipModellingPractice.Objects.Boards;
3 | using BattleshipModellingPractice.Objects.Ships;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace BattleshipModellingPractice.Objects
11 | {
12 | public class Player
13 | {
14 | public string Name { get; set; }
15 | public GameBoard GameBoard { get; set; }
16 | public FiringBoard FiringBoard { get; set; }
17 | public List Ships { get; set; }
18 | public bool HasLost
19 | {
20 | get
21 | {
22 | return Ships.All(x => x.IsSunk);
23 | }
24 | }
25 |
26 | public Player(string name)
27 | {
28 | Name = name;
29 | Ships = new List()
30 | {
31 | new Destroyer(),
32 | new Submarine(),
33 | new Cruiser(),
34 | new Battleship(),
35 | new Carrier()
36 | };
37 | GameBoard = new GameBoard();
38 | FiringBoard = new FiringBoard();
39 | }
40 |
41 | public void OutputBoards()
42 | {
43 | Console.WriteLine(Name);
44 | Console.WriteLine("Own Board: Firing Board:");
45 | for(int row = 1; row <= 10; row++)
46 | {
47 | for(int ownColumn = 1; ownColumn <= 10; ownColumn++)
48 | {
49 | Console.Write(GameBoard.Panels.At(row, ownColumn).Status + " ");
50 | }
51 | Console.Write(" ");
52 | for (int firingColumn = 1; firingColumn <= 10; firingColumn++)
53 | {
54 | Console.Write(FiringBoard.Panels.At(row, firingColumn).Status + " ");
55 | }
56 | Console.WriteLine(Environment.NewLine);
57 | }
58 | Console.WriteLine(Environment.NewLine);
59 | }
60 |
61 | public void PlaceShips()
62 | {
63 | //Random class creation stolen from http://stackoverflow.com/a/18267477/106356
64 | Random rand = new Random(Guid.NewGuid().GetHashCode());
65 | foreach (var ship in Ships)
66 | {
67 | //Select a random row/column combination, then select a random orientation.
68 | //If none of the proposed panels are occupied, place the ship
69 | //Do this for all ships
70 |
71 | bool isOpen = true;
72 | while (isOpen)
73 | {
74 | var startcolumn = rand.Next(1,11);
75 | var startrow = rand.Next(1, 11);
76 | int endrow = startrow, endcolumn = startcolumn;
77 | var orientation = rand.Next(1, 101) % 2; //0 for Horizontal
78 |
79 | List panelNumbers = new List();
80 | if (orientation == 0)
81 | {
82 | for (int i = 1; i < ship.Width; i++)
83 | {
84 | endrow++;
85 | }
86 | }
87 | else
88 | {
89 | for (int i = 1; i < ship.Width; i++)
90 | {
91 | endcolumn++;
92 | }
93 | }
94 |
95 | //We cannot place ships beyond the boundaries of the board
96 | if(endrow > 10 || endcolumn > 10)
97 | {
98 | isOpen = true;
99 | continue;
100 | }
101 |
102 | //Check if specified panels are occupied
103 | var affectedPanels = GameBoard.Panels.Range(startrow, startcolumn, endrow, endcolumn);
104 | if(affectedPanels.Any(x=>x.IsOccupied))
105 | {
106 | isOpen = true;
107 | continue;
108 | }
109 |
110 | foreach(var panel in affectedPanels)
111 | {
112 | panel.OccupationType = ship.OccupationType;
113 | }
114 | isOpen = false;
115 | }
116 | }
117 | }
118 |
119 | public Coordinates FireShot()
120 | {
121 | //If there are hits on the board with neighbors which don't have shots, we should fire at those first.
122 | var hitNeighbors = FiringBoard.GetHitNeighbors();
123 | Coordinates coords;
124 | if (hitNeighbors.Any())
125 | {
126 | coords = SearchingShot();
127 | }
128 | else
129 | {
130 | coords = RandomShot();
131 | }
132 | Console.WriteLine(Name + " says: \"Firing shot at " + coords.Row.ToString() + ", " + coords.Column.ToString() + "\"");
133 | return coords;
134 | }
135 |
136 |
137 | private Coordinates RandomShot()
138 | {
139 | var availablePanels = FiringBoard.GetOpenRandomPanels();
140 | Random rand = new Random(Guid.NewGuid().GetHashCode());
141 | var panelID = rand.Next(availablePanels.Count);
142 | return availablePanels[panelID];
143 | }
144 |
145 | private Coordinates SearchingShot()
146 | {
147 | Random rand = new Random(Guid.NewGuid().GetHashCode());
148 | var hitNeighbors = FiringBoard.GetHitNeighbors();
149 | var neighborID = rand.Next(hitNeighbors.Count);
150 | return hitNeighbors[neighborID];
151 | }
152 |
153 | public ShotResult ProcessShot(Coordinates coords)
154 | {
155 | var panel = GameBoard.Panels.At(coords.Row, coords.Column);
156 | if(!panel.IsOccupied)
157 | {
158 | Console.WriteLine(Name + " says: \"Miss!\"");
159 | return ShotResult.Miss;
160 | }
161 | var ship = Ships.First(x => x.OccupationType == panel.OccupationType);
162 | ship.Hits++;
163 | Console.WriteLine(Name + " says: \"Hit!\"");
164 | if (ship.IsSunk)
165 | {
166 | Console.WriteLine(Name + " says: \"You sunk my " + ship.Name + "!\"");
167 | }
168 | return ShotResult.Hit;
169 | }
170 |
171 | public void ProcessShotResult(Coordinates coords, ShotResult result)
172 | {
173 | var panel = FiringBoard.Panels.At(coords.Row, coords.Column);
174 | switch(result)
175 | {
176 | case ShotResult.Hit:
177 | panel.OccupationType = OccupationType.Hit;
178 | break;
179 |
180 | default:
181 | panel.OccupationType = OccupationType.Miss;
182 | break;
183 | }
184 | }
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Ships/Battleship.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BattleshipModellingPractice.Objects.Ships
8 | {
9 | public class Battleship : Ship
10 | {
11 | public Battleship()
12 | {
13 | Name = "Battleship";
14 | Width = 4;
15 | OccupationType = OccupationType.Battleship;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Ships/Carrier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BattleshipModellingPractice.Objects.Ships
8 | {
9 | public class Carrier : Ship
10 | {
11 | public Carrier()
12 | {
13 | Name = "Aircraft Carrier";
14 | Width = 5;
15 | OccupationType = OccupationType.Carrier;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Ships/Cruiser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BattleshipModellingPractice.Objects.Ships
8 | {
9 | public class Cruiser : Ship
10 | {
11 | public Cruiser()
12 | {
13 | Name = "Cruiser";
14 | Width = 3;
15 | OccupationType = OccupationType.Cruiser;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Ships/Destroyer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BattleshipModellingPractice.Objects.Ships
8 | {
9 | public class Destroyer : Ship
10 | {
11 | public Destroyer()
12 | {
13 | Name = "Destroyer";
14 | Width = 2;
15 | OccupationType = OccupationType.Destroyer;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Ships/Ship.cs:
--------------------------------------------------------------------------------
1 | using BattleshipModellingPractice.Objects.Boards;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace BattleshipModellingPractice.Objects
9 | {
10 | ///
11 | /// Represents a player's ship as placed on their Game Board.
12 | ///
13 | public abstract class Ship
14 | {
15 | public string Name { get; set; }
16 | public int Width { get; set; }
17 | public int Hits { get; set; }
18 | public OccupationType OccupationType { get; set; }
19 | public bool IsSunk
20 | {
21 | get
22 | {
23 | return Hits >= Width;
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Objects/Ships/Submarine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BattleshipModellingPractice.Objects.Ships
8 | {
9 | public class Submarine : Ship
10 | {
11 | public Submarine()
12 | {
13 | Name = "Submarine";
14 | Width = 3;
15 | OccupationType = OccupationType.Submarine;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Program.cs:
--------------------------------------------------------------------------------
1 | using BattleshipModellingPractice.Objects;
2 | using BattleshipModellingPractice.Objects.Games;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace BattleshipModellingPractice
10 | {
11 | class Program
12 | {
13 | static void Main(string[] args)
14 | {
15 | int player1Wins = 0, player2Wins = 0;
16 |
17 | Console.WriteLine("How many games do you want to play?");
18 | var numGames = int.Parse(Console.ReadLine());
19 |
20 | for (int i = 0; i < numGames; i++)
21 | {
22 | Game game1 = new Game();
23 | game1.PlayToEnd();
24 | if(game1.Player1.HasLost)
25 | {
26 | player2Wins++;
27 | }
28 | else
29 | {
30 | player1Wins++;
31 | }
32 | }
33 |
34 | Console.WriteLine("Player 1 Wins: " + player1Wins.ToString());
35 | Console.WriteLine("Player 2 Wins: " + player2Wins.ToString());
36 | Console.ReadLine();
37 |
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/BattleshipModellingPractice/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("BattleshipModellingPractice")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("BattleshipModellingPractice")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("dc5a4b6f-fd2f-438c-8d0b-6ccd5f06e1dc")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BattleshipModellingPractice
2 |
3 | As part of my [Modeling Practice](https://exceptionnotfound.net/tag/modeling-practice/) series, this project is intended to model the board game Battleship as a C# program.
4 |
5 | You can read more about it on my blog:
6 |
7 | 1. [Part 1: Introduction and Strategies](https://exceptionnotfound.net/modeling-battleship-in-csharp-introduction-and-strategies/)
8 | 2. [Part 2: Components and Setup](https://exceptionnotfound.net/modeling-battleship-in-csharp-components-and-setup/)
9 | 3. [Part 3: Playing the Game](https://exceptionnotfound.net/modeling-battleship-in-csharp-playing-the-game/)
10 |
--------------------------------------------------------------------------------