├── Tetris (.NET Core)
├── TetrisClassDiagram.cd
├── IInputHandler.cs
├── Tetris.csproj
├── TetrisGameInput.cs
├── AiInputHandler.cs
├── LineTetrisGame.cs
├── ITetrisGame.cs
├── Program.cs
├── Tetromino.cs
├── Tetris.sln
├── ConsoleInputHandler.cs
├── ScoreManager.cs
├── GameManager.cs
├── TetrisConsoleWriter.cs
├── MusicPlayer.cs
└── TetrisGame.cs
├── TicTacToe
├── TicTacToe
│ ├── Symbol.cs
│ ├── Players
│ │ ├── IPlayer.cs
│ │ ├── RandomPlayer.cs
│ │ ├── ConsolePlayer.cs
│ │ └── AiPlayer.cs
│ ├── TicTacToe.csproj
│ ├── GameResult.cs
│ ├── IBoard.cs
│ ├── Index.cs
│ ├── TicTacToeGame.cs
│ ├── GameWinnerLogic.cs
│ ├── Board.cs
│ └── Program.cs
├── TicTacToeTests
│ ├── TicTacToeTests.csproj
│ ├── TicTacToeGameTests.cs
│ └── BoardTests.cs
└── TicTacToe.sln
├── BreakOut
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── BreakOut.csproj
└── Program.cs
├── Cars
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── Cars.csproj
└── Program.cs
├── PingPong
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── PingPong.csproj
└── Program.cs
├── Snake
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── Snake.csproj
└── Program.cs
├── Tetris
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── readme.txt
├── Tetris.csproj
└── Program.cs
├── Tron
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── Tron.csproj
└── Program.cs
├── .github
└── FUNDING.yml
├── azure-pipelines.yml
├── README.md
├── LICENSE
├── .gitignore
├── .gitattributes
└── CSharpConsoleGames.sln
/Tetris (.NET Core)/TetrisClassDiagram.cd:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/IInputHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Tetris
2 | {
3 | public interface IInputHandler
4 | {
5 | TetrisGameInput GetInput();
6 | }
7 | }
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/Symbol.cs:
--------------------------------------------------------------------------------
1 | namespace TicTacToe
2 | {
3 | public enum Symbol
4 | {
5 | None = 0,
6 | X = 1,
7 | O = 2,
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/Players/IPlayer.cs:
--------------------------------------------------------------------------------
1 | namespace TicTacToe.Players
2 | {
3 | public interface IPlayer
4 | {
5 | Index Play(Board board, Symbol symbol);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/BreakOut/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Cars/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/PingPong/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Snake/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Tetris/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Tron/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/TicTacToe.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net5.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/Tetris.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.2
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/TetrisGameInput.cs:
--------------------------------------------------------------------------------
1 | namespace Tetris
2 | {
3 | public enum TetrisGameInput
4 | {
5 | None = 0,
6 | Left = 1,
7 | Right = 2,
8 | Down = 3,
9 | Rotate = 4,
10 | Exit = 99,
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/GameResult.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 TicTacToe
8 | {
9 | public class GameResult
10 | {
11 | public GameResult(Symbol winner, Board board)
12 | {
13 | Winner = winner;
14 | Board = board;
15 | }
16 |
17 | public Symbol Winner { get; }
18 | public Board Board { get; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/IBoard.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace TicTacToe
4 | {
5 | public interface IBoard
6 | {
7 | bool IsFull();
8 |
9 | void PlaceSymbol(Index index, Symbol symbol);
10 |
11 | IEnumerable GetEmptyPositions();
12 |
13 | Symbol GetRowSymbol(int row);
14 |
15 | Symbol GetColumnSymbol(int column);
16 |
17 | Symbol GetDiagonalTLBRSymbol();
18 |
19 | Symbol GetDiagonalTRBLSymbol();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/AiInputHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Tetris
6 | {
7 | public class AiInputHandler : IInputHandler
8 | {
9 | private readonly TetrisGame game;
10 |
11 | public AiInputHandler(TetrisGame game)
12 | {
13 | this.game = game;
14 | }
15 |
16 | public TetrisGameInput GetInput()
17 | {
18 | return TetrisGameInput.Down;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/LineTetrisGame.cs:
--------------------------------------------------------------------------------
1 | namespace Tetris
2 | {
3 | public class LineTetrisGame : TetrisGame
4 | {
5 | public LineTetrisGame(int tetrisRows, int tetrisColumns) :
6 | base(tetrisRows, tetrisColumns)
7 | {
8 | }
9 |
10 | public override void NewRandomFigure()
11 | {
12 | this.CurrentFigure = TetrisFigures[0].GetRotate();
13 | this.CurrentFigureRow = 0;
14 | this.CurrentFigureCol = this.TetrisColumns / 2 - this.CurrentFigure.Width / 2;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/ITetrisGame.cs:
--------------------------------------------------------------------------------
1 | namespace Tetris
2 | {
3 | public interface ITetrisGame
4 | {
5 | Tetromino CurrentFigure { get; set; }
6 | int CurrentFigureCol { get; set; }
7 | int CurrentFigureRow { get; set; }
8 | int Level { get; }
9 | int TetrisColumns { get; }
10 | bool[,] TetrisField { get; }
11 | int TetrisRows { get; }
12 |
13 | void AddCurrentFigureToTetrisField();
14 | int CheckForFullLines();
15 | bool Collision(Tetromino figure);
16 | void NewRandomFigure();
17 | void UpdateLevel(int score);
18 | bool CanMoveToLeft();
19 | bool CanMoveToRight();
20 | }
21 | }
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/Players/RandomPlayer.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 TicTacToe.Players
8 | {
9 | public class RandomPlayer : IPlayer
10 | {
11 | private Random random;
12 |
13 | public RandomPlayer()
14 | {
15 | this.random = new Random();
16 | }
17 |
18 | public Index Play(Board board, Symbol symbol)
19 | {
20 | var availablePositions = board.GetEmptyPositions().ToList();
21 | return availablePositions[random.Next(0, availablePositions.Count)];
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Tetris
2 | {
3 | // TODO: When we have collision during moving (left/right) we have unusual behaviour
4 | public static class Program
5 | {
6 | public static void Main()
7 | {
8 | new MusicPlayer().Play();
9 | int TetrisRows = 20;
10 | int TetrisCols = 10;
11 | var gameManager = new TetrisGameManager(
12 | new TetrisGame(TetrisRows, TetrisCols),
13 | new ConsoleInputHandler(),
14 | new TetrisConsoleWriter(TetrisRows, TetrisCols, '▓'),
15 | new ScoreManager("scores.txt"));
16 | gameManager.MainLoop();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToeTests/TicTacToeTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 |
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: NikolayIT # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | # .NET Desktop
2 | # Build and run tests for .NET Desktop or Windows classic desktop solutions.
3 | # Add steps that publish symbols, save build artifacts, and more:
4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net
5 |
6 | trigger:
7 | - master
8 |
9 | pool:
10 | vmImage: 'windows-latest'
11 |
12 | variables:
13 | solution: '**/*.sln'
14 | buildPlatform: 'Any CPU'
15 | buildConfiguration: 'Release'
16 |
17 | steps:
18 | - task: NuGetToolInstaller@1
19 |
20 | - task: NuGetCommand@2
21 | inputs:
22 | restoreSolution: '$(solution)'
23 |
24 | - task: VSBuild@1
25 | inputs:
26 | solution: '$(solution)'
27 | platform: '$(buildPlatform)'
28 | configuration: '$(buildConfiguration)'
29 |
30 | - task: VSTest@2
31 | inputs:
32 | platform: '$(buildPlatform)'
33 | configuration: '$(buildConfiguration)'
34 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/Tetromino.cs:
--------------------------------------------------------------------------------
1 | namespace Tetris
2 | {
3 | public class Tetromino
4 | {
5 | public Tetromino(bool[,] body)
6 | {
7 | this.Body = body;
8 | }
9 |
10 | public bool[,] Body { get; private set; }
11 |
12 | public int Width => this.Body.GetLength(0);
13 |
14 | public int Height => this.Body.GetLength(1);
15 |
16 | public Tetromino GetRotate()
17 | {
18 | var newFigure = new bool[this.Height, this.Width];
19 | for (int row = 0; row < this.Width; row++)
20 | {
21 | for (int col = 0; col < this.Height; col++)
22 | {
23 | newFigure[col, this.Width - row - 1] = this.Body[row, col];
24 | }
25 | }
26 |
27 | return new Tetromino(newFigure);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | C# Console Games
2 | ================
3 |
4 | Source code for some C# console games with video explanation **in Bulgarian**
5 |
6 | * Cars (2012): http://www.youtube.com/watch?v=bQexyufgclY
7 | * PingPong (2012): http://www.youtube.com/watch?v=DmkqnjsNKZM
8 | * Snake (2012): http://www.youtube.com/watch?v=dXng0W0R_Ks
9 | * Tron (2013): http://www.youtube.com/watch?v=yccxWRsQBB0
10 | * Tetris (2014): https://www.youtube.com/watch?v=0-WOuN0qqI0
11 | * Tetris (.NET Core) (2019)
12 | * Creating Tetris part 1 - https://youtu.be/_-JyqwaLjVM
13 | * Creating Tetris part 2 - https://youtu.be/lWsm3ZTSnt0
14 | * Creating Tetris part 3 - https://youtu.be/VBxFekjsGPc
15 | * Refactoring Tetris with OOP part 1 - https://youtu.be/SmDNHr3uL-E
16 | * Refactoring Tetris with OOP part 2 - https://youtu.be/v2mEpgxSB6A
17 | * Refactoring Tetris with OOP part 3 - https://youtu.be/IjO38LeZuHY
18 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/Index.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TicTacToe
4 | {
5 | public class Index
6 | {
7 | public Index(int row, int column)
8 | {
9 | this.Row = row;
10 | this.Column = column;
11 | }
12 |
13 | public Index(string str)
14 | {
15 | var parts = str.Split(',');
16 | this.Row = int.Parse(parts[0]);
17 | this.Column = int.Parse(parts[1]);
18 | }
19 |
20 | public int Row { get; set; }
21 |
22 | public int Column { get; set; }
23 |
24 | public override bool Equals(object obj)
25 | {
26 | var otherIndex = obj as Index;
27 |
28 | return this.Row == otherIndex.Row &&
29 | this.Column == otherIndex.Column;
30 | }
31 |
32 | public override string ToString()
33 | {
34 | return $"{this.Row},{this.Column}";
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Nikolay Kostov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/Tetris.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29424.173
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tetris", "Tetris.csproj", "{11966FD9-189C-4182-A367-B6EAE5CB2956}"
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 | {11966FD9-189C-4182-A367-B6EAE5CB2956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {11966FD9-189C-4182-A367-B6EAE5CB2956}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {11966FD9-189C-4182-A367-B6EAE5CB2956}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {11966FD9-189C-4182-A367-B6EAE5CB2956}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {55EF1901-EC2A-4958-9118-D702528D4E66}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/Players/ConsolePlayer.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 TicTacToe.Players
8 | {
9 | public class ConsolePlayer : IPlayer
10 | {
11 | public Index Play(Board board, Symbol symbol)
12 | {
13 | // Console.Clear();
14 | Console.WriteLine(board.ToString());
15 | Index position;
16 | while (true)
17 | {
18 | Console.Write($"{symbol} Please enter position (0,0): ");
19 | var line = Console.ReadLine();
20 | try
21 | {
22 | position = new Index(line);
23 | }
24 | catch
25 | {
26 | Console.WriteLine("Invalid position format!");
27 | continue;
28 | }
29 |
30 | if (!board.GetEmptyPositions().Any(x => x.Equals(position)))
31 | {
32 | Console.WriteLine("This position is not available!");
33 | continue;
34 | }
35 |
36 | break;
37 | }
38 |
39 | return position;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/ConsoleInputHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Tetris
4 | {
5 | public class ConsoleInputHandler : IInputHandler
6 | {
7 | public TetrisGameInput GetInput()
8 | {
9 | // Read user input
10 | if (Console.KeyAvailable)
11 | {
12 | var key = Console.ReadKey();
13 | if (key.Key == ConsoleKey.Escape)
14 | {
15 | return TetrisGameInput.Exit;
16 | }
17 | if (key.Key == ConsoleKey.LeftArrow || key.Key == ConsoleKey.A)
18 | {
19 | return TetrisGameInput.Left;
20 | }
21 | if (key.Key == ConsoleKey.RightArrow || key.Key == ConsoleKey.D)
22 | {
23 | return TetrisGameInput.Right;
24 | }
25 | if (key.Key == ConsoleKey.DownArrow || key.Key == ConsoleKey.S)
26 | {
27 | return TetrisGameInput.Down;
28 | }
29 | if (key.Key == ConsoleKey.Spacebar || key.Key == ConsoleKey.UpArrow || key.Key == ConsoleKey.W)
30 | {
31 | return TetrisGameInput.Rotate;
32 | }
33 | }
34 |
35 | return TetrisGameInput.None;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Cars/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("Cars")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Cars")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
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("fecba82a-4d2f-4e52-88a2-f9eac8fc27e6")]
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 |
--------------------------------------------------------------------------------
/Tron/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("Tron")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Tron")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
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("4e3faaf1-6b6c-41b4-8521-78687b2d1e48")]
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 |
--------------------------------------------------------------------------------
/Snake/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("Snake")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Snake")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
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("ddbc4e05-30b4-49af-8d1c-7d1b1cd03c80")]
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 |
--------------------------------------------------------------------------------
/Tetris/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("Tetris")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Tetris")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
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("976f57d9-bba8-4f78-85f5-c7d7975738fe")]
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 |
--------------------------------------------------------------------------------
/BreakOut/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("BreakOut")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("BreakOut")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
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("69f6f354-3554-4014-828d-230ba5e2b234")]
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 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/TicTacToeGame.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using TicTacToe.Players;
3 |
4 | namespace TicTacToe
5 | {
6 | public class TicTacToeGame
7 | {
8 | public TicTacToeGame(IPlayer firstPlayer, IPlayer secondPlayer)
9 | {
10 | FirstPlayer = firstPlayer;
11 | SecondPlayer = secondPlayer;
12 | this.WinnerLogic = new GameWinnerLogic();
13 | }
14 |
15 | public IPlayer FirstPlayer { get; }
16 | public IPlayer SecondPlayer { get; }
17 | public GameWinnerLogic WinnerLogic { get; }
18 |
19 | public GameResult Play()
20 | {
21 | Board board = new Board();
22 | IPlayer currentPlayer = this.FirstPlayer;
23 | Symbol symbol = Symbol.X;
24 | while (!this.WinnerLogic.IsGameOver(board))
25 | {
26 | // Play round
27 | var move = currentPlayer.Play(board, symbol);
28 | board.PlaceSymbol(move, symbol);
29 |
30 | if (currentPlayer == this.FirstPlayer)
31 | {
32 | currentPlayer = this.SecondPlayer;
33 | symbol = Symbol.O;
34 | }
35 | else
36 | {
37 | currentPlayer = this.FirstPlayer;
38 | symbol = Symbol.X;
39 | }
40 | }
41 |
42 | var winner = this.WinnerLogic.GetWinner(board);
43 | return new GameResult(winner, board);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/PingPong/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("PingPong")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("PingPong")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
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("2f1bffa3-2fce-4244-80d4-c3f123be2f18")]
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 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31911.196
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TicTacToe", "TicTacToe\TicTacToe.csproj", "{A7AA2456-3101-4BEE-B16F-CE57EF77B8C4}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TicTacToeTests", "TicTacToeTests\TicTacToeTests.csproj", "{70BE93FA-F5EE-49A7-8C3D-D8F5E9AB17D1}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {A7AA2456-3101-4BEE-B16F-CE57EF77B8C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {A7AA2456-3101-4BEE-B16F-CE57EF77B8C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {A7AA2456-3101-4BEE-B16F-CE57EF77B8C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {A7AA2456-3101-4BEE-B16F-CE57EF77B8C4}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {70BE93FA-F5EE-49A7-8C3D-D8F5E9AB17D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {70BE93FA-F5EE-49A7-8C3D-D8F5E9AB17D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {70BE93FA-F5EE-49A7-8C3D-D8F5E9AB17D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {70BE93FA-F5EE-49A7-8C3D-D8F5E9AB17D1}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {0BCB4B9B-1716-4E2E-A4A4-25D13D54CF1A}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToeTests/TicTacToeGameTests.cs:
--------------------------------------------------------------------------------
1 | using Moq;
2 | using NUnit.Framework;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using TicTacToe;
9 | using TicTacToe.Players;
10 | using Index = TicTacToe.Index;
11 |
12 | namespace TicTacToeTests
13 | {
14 | [TestFixture]
15 | public class TicTacToeGameTests
16 | {
17 | [Test]
18 | public void PlayShouldReturnValue()
19 | {
20 | var player = new Mock();
21 | player.Setup(x => x.Play(It.IsAny(), It.IsAny()))
22 | .Returns((Board x, Symbol s) =>
23 | {
24 | return x.GetEmptyPositions().First();
25 | });
26 |
27 | var game = new TicTacToeGame(player.Object, player.Object);
28 | }
29 |
30 | [Test]
31 | public void PlayShouldReturnCorrectWinner()
32 | {
33 | int player1CurrentCol = 0;
34 | int player2CurrentCol = 0;
35 | var player1 = new Mock();
36 | player1.Setup(x => x.Play(It.IsAny(), It.IsAny()))
37 | .Returns((Board x, Symbol s) => new Index(0, player1CurrentCol++));
38 | var player2 = new Mock();
39 | player2.Setup(x => x.Play(It.IsAny(), It.IsAny()))
40 | .Returns((Board x, Symbol s) => new Index(1, player2CurrentCol++));
41 |
42 | var game = new TicTacToeGame(player1.Object, player2.Object);
43 | var winner = game.Play();
44 | Assert.AreEqual(Symbol.X, winner);
45 | }
46 |
47 | // TODO: Add more tests
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/ScoreManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text.RegularExpressions;
5 |
6 | namespace Tetris
7 | {
8 | public class ScoreManager
9 | {
10 | private readonly string highScoreFile;
11 |
12 | private readonly int[] ScorePerLines = { 1, 40, 100, 300, 1200 };
13 |
14 | public ScoreManager(string highScoreFile)
15 | {
16 | this.highScoreFile = highScoreFile;
17 | this.HighScore = this.GetHighScore();
18 | }
19 |
20 | public int Score { get; private set; }
21 |
22 | public int HighScore { get; private set; }
23 |
24 | public void AddToScore(int level, int lines)
25 | {
26 | this.Score += ScorePerLines[lines] * level;
27 | if (this.Score > this.HighScore)
28 | {
29 | this.HighScore = this.Score;
30 | }
31 | }
32 |
33 | public void AddToHighScore()
34 | {
35 | File.AppendAllLines(this.highScoreFile, new List
36 | {
37 | $"[{DateTime.Now.ToString()}] {Environment.UserName} => {this.Score}"
38 | });
39 | }
40 |
41 | private int GetHighScore()
42 | {
43 | var highScore = 0;
44 | if (File.Exists(this.highScoreFile))
45 | {
46 | var allScores = File.ReadAllLines(this.highScoreFile);
47 | foreach (var score in allScores)
48 | {
49 | var match = Regex.Match(score, @" => (?[0-9]+)");
50 | highScore = Math.Max(highScore, int.Parse(match.Groups["score"].Value));
51 | }
52 | }
53 |
54 | return highScore;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Tetris/readme.txt:
--------------------------------------------------------------------------------
1 | http://en.wikipedia.org/wiki/Tetris
2 | Standard tetris - 16 rows, 10 columns
3 | color landed[16, 10]
4 |
5 |
6 | Tetriminos (http://en.wikipedia.org/wiki/Tetris#Colors_of_Tetriminos)
7 | I **** (red)
8 |
9 | J *** (blue)
10 | *
11 |
12 | L *** (orange)
13 | *
14 |
15 | O ** (yellow)
16 | **
17 |
18 | S ** (magenta)
19 | **
20 |
21 | T *** (cyan)
22 | *
23 |
24 | Z ** (lime)
25 | **
26 |
27 |
28 | Gravity (http://en.wikipedia.org/wiki/Tetris#Gravity)
29 | Original algorithm (with floating)
30 | Algorithm with chain reactions
31 |
32 |
33 | Scoring (http://tetris.wikia.com/wiki/Scoring)
34 | 1 line at once = 100 x level
35 | 2 lines at once = 300 x level
36 | 3 lines at once = 500 x level
37 | 4 lines at once = 800 x level
38 |
39 |
40 | UI (http://en.wikipedia.org/wiki/ASCII http://www.theasciicode.com.ar/extended-ascii-code/block-graphic-character-ascii-code-219.html)
41 | ***********************
42 | *..........* Next *
43 | *..........* ** *
44 | *..........* ** *
45 | *..........* *
46 | *..........* Score: *
47 | *..........* 100000 *
48 | *..........* *
49 | *..........* Level: *
50 | *..........* 8 *
51 | *..........* *
52 | *..........* Controls *
53 | *..........* ^ *
54 | *..........* < > *
55 | *..........* v *
56 | *..........* space *
57 | *..........* *
58 | ***********************
59 | Console.Title = "Tetris";
60 | Console.WindowWidth = 23;
61 | Console.BufferWidth = 23;
62 | Console.WindowHeight = 18;
63 | Console.BufferHeight = 18;
64 | Console.OutputEncoding = System.Text.Encoding.GetEncoding(1252);
65 |
66 |
67 | Sound
68 | Beep sound with tetris notes
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
2 | [Bb]in/
3 | [Oo]bj/
4 |
5 | # mstest test results
6 | TestResults
7 |
8 | ## Ignore Visual Studio temporary files, build results, and
9 | ## files generated by popular Visual Studio add-ons.
10 |
11 | # User-specific files
12 | *.suo
13 | *.user
14 | *.sln.docstates
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Rr]elease/
19 | x64/
20 | *_i.c
21 | *_p.c
22 | *.ilk
23 | *.meta
24 | *.obj
25 | *.pch
26 | *.pdb
27 | *.pgc
28 | *.pgd
29 | *.rsp
30 | *.sbr
31 | *.tlb
32 | *.tli
33 | *.tlh
34 | *.tmp
35 | *.log
36 | *.vspscc
37 | *.vssscc
38 | .builds
39 |
40 | # Visual C++ cache files
41 | ipch/
42 | *.aps
43 | *.ncb
44 | *.opensdf
45 | *.sdf
46 |
47 | # Visual Studio profiler
48 | *.psess
49 | *.vsp
50 | *.vspx
51 |
52 | # Guidance Automation Toolkit
53 | *.gpState
54 |
55 | # ReSharper is a .NET coding add-in
56 | _ReSharper*
57 |
58 | # NCrunch
59 | *.ncrunch*
60 | .*crunch*.local.xml
61 |
62 | # Installshield output folder
63 | [Ee]xpress
64 |
65 | # DocProject is a documentation generator add-in
66 | DocProject/buildhelp/
67 | DocProject/Help/*.HxT
68 | DocProject/Help/*.HxC
69 | DocProject/Help/*.hhc
70 | DocProject/Help/*.hhk
71 | DocProject/Help/*.hhp
72 | DocProject/Help/Html2
73 | DocProject/Help/html
74 |
75 | # Click-Once directory
76 | publish
77 |
78 | # Publish Web Output
79 | *.Publish.xml
80 |
81 | # NuGet Packages Directory
82 | packages
83 |
84 | # Windows Azure Build Output
85 | csx
86 | *.build.csdef
87 |
88 | # Windows Store app package directory
89 | AppPackages/
90 |
91 | # Others
92 | [Bb]in
93 | [Oo]bj
94 | sql
95 | TestResults
96 | [Tt]est[Rr]esult*
97 | *.Cache
98 | ClientBin
99 | [Ss]tyle[Cc]op.*
100 | ~$*
101 | *.dbmdl
102 | Generated_Code #added for RIA/Silverlight projects
103 |
104 | # Backup & report files from converting an old project file to a newer
105 | # Visual Studio version. Backup files are not needed, because we have git ;-)
106 | _UpgradeReport_Files/
107 | Backup*/
108 | UpgradeLog*.XML
109 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/GameWinnerLogic.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 TicTacToe
8 | {
9 | public class GameWinnerLogic
10 | {
11 | public bool IsGameOver(Board board)
12 | {
13 | for (int row = 0; row < board.Rows; row++)
14 | {
15 | if (board.GetRowSymbol(row) != Symbol.None)
16 | {
17 | return true;
18 | }
19 | }
20 |
21 | for (int col = 0; col < board.Columns; col++)
22 | {
23 | if (board.GetColumnSymbol(col) != Symbol.None)
24 | {
25 | return true;
26 | }
27 | }
28 |
29 | if (board.GetDiagonalTLBRSymbol() != Symbol.None)
30 | {
31 | return true;
32 | }
33 |
34 | if (board.GetDiagonalTRBLSymbol() != Symbol.None)
35 | {
36 | return true;
37 | }
38 |
39 | return board.IsFull();
40 | }
41 |
42 | public Symbol GetWinner(Board board)
43 | {
44 | for (int row = 0; row < board.Rows; row++)
45 | {
46 | var winner = board.GetRowSymbol(row);
47 | if (winner != Symbol.None)
48 | {
49 | return winner;
50 | }
51 | }
52 |
53 | for (int col = 0; col < board.Columns; col++)
54 | {
55 | var winner = board.GetColumnSymbol(col);
56 | if (winner != Symbol.None)
57 | {
58 | return winner;
59 | }
60 | }
61 |
62 | var diagonal1 = board.GetDiagonalTLBRSymbol();
63 | if (diagonal1 != Symbol.None)
64 | {
65 | return diagonal1;
66 | }
67 |
68 | var diagonal2 = board.GetDiagonalTRBLSymbol();
69 | if (diagonal2 != Symbol.None)
70 | {
71 | return diagonal2;
72 | }
73 |
74 | return Symbol.None;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/Players/AiPlayer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TicTacToe.Players
4 | {
5 | // TODO: Set depth limit
6 | public class AiPlayer : IPlayer
7 | {
8 | public AiPlayer()
9 | {
10 | this.WinnerLogic = new GameWinnerLogic();
11 | }
12 |
13 | public GameWinnerLogic WinnerLogic { get; }
14 |
15 | public Index Play(Board board, Symbol symbol)
16 | {
17 | // Instead best move -> best moveS
18 | Index bestMove = null;
19 | int bestMoveValue = -1000;
20 | var moves = board.GetEmptyPositions();
21 | foreach (var move in moves)
22 | {
23 | board.PlaceSymbol(move, symbol);
24 | var value = MiniMax(board, symbol, symbol == Symbol.X ? Symbol.O : Symbol.X);
25 | board.PlaceSymbol(move, Symbol.None);
26 | if (value > bestMoveValue)
27 | {
28 | bestMove = move;
29 | bestMoveValue = value;
30 | }
31 |
32 | // if (value == bestMoveValue) add to list
33 | }
34 |
35 | return bestMove;
36 | }
37 |
38 | private int MiniMax(Board board, Symbol player, Symbol currentPlayer)
39 | {
40 | if (this.WinnerLogic.IsGameOver(board))
41 | {
42 | var winner = this.WinnerLogic.GetWinner(board);
43 | if (winner == player) return 1;
44 | else if (winner == Symbol.None) return 0;
45 | else return -1;
46 | }
47 |
48 | var bestValue = player == currentPlayer ? -100 : 100; // TODO:
49 | var options = board.GetEmptyPositions();
50 | foreach (var option in options)
51 | {
52 | board.PlaceSymbol(option, currentPlayer);
53 | var value = MiniMax(board, player, currentPlayer == Symbol.O ? Symbol.X : Symbol.O);
54 | board.PlaceSymbol(option, Symbol.None);
55 | bestValue =
56 | currentPlayer == player ?
57 | Math.Max(bestValue, value) :
58 | Math.Min(bestValue, value);
59 | }
60 |
61 | return bestValue;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/BreakOut/BreakOut.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {69F6F354-3554-4014-828D-230BA5E2B234}
8 | Exe
9 | BreakOut
10 | BreakOut
11 | v4.5
12 | 512
13 | true
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Cars/Cars.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {45BB87DC-35A8-4CAC-AECD-EB35F4F971FE}
8 | Exe
9 | Properties
10 | Cars
11 | Cars
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
58 |
--------------------------------------------------------------------------------
/Tron/Tron.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {7331B390-A4D9-4CB9-8FF9-106DD2B181CB}
8 | Exe
9 | Properties
10 | Tron
11 | Tron
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
58 |
--------------------------------------------------------------------------------
/Snake/Snake.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {3AFB18FB-ECDC-40FE-B10E-3B34C2B8D610}
8 | Exe
9 | Properties
10 | Snake
11 | Snake
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
58 |
--------------------------------------------------------------------------------
/Tetris/Tetris.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B920B046-AC8E-4B85-A4BB-A81C1A235BA8}
8 | Exe
9 | Properties
10 | Tetris
11 | Tetris
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
58 |
--------------------------------------------------------------------------------
/PingPong/PingPong.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {335C946F-00E6-4888-A009-827E6B0AAD20}
8 | Exe
9 | Properties
10 | PingPong
11 | PingPong
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
58 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToeTests/BoardTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using TicTacToe;
8 |
9 | namespace TicTacToeTests
10 | {
11 | [TestFixture]
12 | public class BoardTests
13 | {
14 | [Test]
15 | public void IsFullShouldReturnTrueForFullBoard()
16 | {
17 | var board = new Board(3,3);
18 | Assert.IsFalse(board.IsFull());
19 |
20 | for (int i = 0; i < 3; i++)
21 | {
22 | for (int j = 0; j < 3; j++)
23 | {
24 | Assert.IsFalse(board.IsFull());
25 | board.PlaceSymbol(new TicTacToe.Index(i, j), Symbol.X);
26 | }
27 | }
28 |
29 | Assert.IsTrue(board.IsFull());
30 | }
31 |
32 | [Test]
33 | public void GetRowSymbolShouldWorkCorrectly()
34 | {
35 | var board = new Board(4, 4);
36 |
37 | for (int i = 0; i < board.Columns; i++)
38 | {
39 | Assert.AreEqual(Symbol.None, board.GetRowSymbol(2));
40 | board.PlaceSymbol(
41 | new TicTacToe.Index(2, i),
42 | Symbol.O);
43 | }
44 |
45 | Assert.AreEqual(Symbol.O, board.GetRowSymbol(2));
46 | }
47 |
48 | [TestCase(Symbol.X)]
49 | [TestCase(Symbol.O)]
50 | public void GetColumnSymbolShouldWorkCorrectly(Symbol symbol)
51 | {
52 | var board = new Board(5, 5);
53 |
54 | for (int i = 0; i < board.Rows; i++)
55 | {
56 | Assert.AreEqual(Symbol.None, board.GetColumnSymbol(2));
57 | board.PlaceSymbol(
58 | new TicTacToe.Index(i, 1),
59 | symbol);
60 | }
61 |
62 | Assert.AreEqual(symbol, board.GetColumnSymbol(1));
63 | }
64 |
65 | // TODO: Test GetDiagonalTLBRSymbol()
66 | // TODO: Test GetDiagonalTRBLSymbol()
67 | // TODO: Test ToString()
68 |
69 | [Test]
70 | public void GetEmptyPositionsShouldReturnAllPositionsForEmptyBoard()
71 | {
72 | var board = new Board(3, 3);
73 | var positions = board.GetEmptyPositions();
74 | Assert.AreEqual(3 * 3, positions.Count());
75 | }
76 |
77 | [Test]
78 | public void GetEmptyPositionsShouldReturnCorrectNumberOfPositions()
79 | {
80 | var board = new Board(4, 4);
81 | board.PlaceSymbol(new TicTacToe.Index(1, 1), Symbol.X);
82 | board.PlaceSymbol(new TicTacToe.Index(2, 2), Symbol.O);
83 | var positions = board.GetEmptyPositions();
84 | Assert.AreEqual(4*4-2, positions.Count());
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/CSharpConsoleGames.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.30723.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Snake", "Snake\Snake.csproj", "{3AFB18FB-ECDC-40FE-B10E-3B34C2B8D610}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cars", "Cars\Cars.csproj", "{45BB87DC-35A8-4CAC-AECD-EB35F4F971FE}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PingPong", "PingPong\PingPong.csproj", "{335C946F-00E6-4888-A009-827E6B0AAD20}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tron", "Tron\Tron.csproj", "{7331B390-A4D9-4CB9-8FF9-106DD2B181CB}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tetris", "Tetris\Tetris.csproj", "{B920B046-AC8E-4B85-A4BB-A81C1A235BA8}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BreakOut", "BreakOut\BreakOut.csproj", "{69F6F354-3554-4014-828D-230BA5E2B234}"
17 | EndProject
18 | Global
19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 | Debug|Any CPU = Debug|Any CPU
21 | Release|Any CPU = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 | {3AFB18FB-ECDC-40FE-B10E-3B34C2B8D610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {3AFB18FB-ECDC-40FE-B10E-3B34C2B8D610}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {3AFB18FB-ECDC-40FE-B10E-3B34C2B8D610}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {3AFB18FB-ECDC-40FE-B10E-3B34C2B8D610}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {45BB87DC-35A8-4CAC-AECD-EB35F4F971FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {45BB87DC-35A8-4CAC-AECD-EB35F4F971FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {45BB87DC-35A8-4CAC-AECD-EB35F4F971FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {45BB87DC-35A8-4CAC-AECD-EB35F4F971FE}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {335C946F-00E6-4888-A009-827E6B0AAD20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {335C946F-00E6-4888-A009-827E6B0AAD20}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {335C946F-00E6-4888-A009-827E6B0AAD20}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {335C946F-00E6-4888-A009-827E6B0AAD20}.Release|Any CPU.Build.0 = Release|Any CPU
36 | {7331B390-A4D9-4CB9-8FF9-106DD2B181CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {7331B390-A4D9-4CB9-8FF9-106DD2B181CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {7331B390-A4D9-4CB9-8FF9-106DD2B181CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {7331B390-A4D9-4CB9-8FF9-106DD2B181CB}.Release|Any CPU.Build.0 = Release|Any CPU
40 | {B920B046-AC8E-4B85-A4BB-A81C1A235BA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41 | {B920B046-AC8E-4B85-A4BB-A81C1A235BA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 | {B920B046-AC8E-4B85-A4BB-A81C1A235BA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 | {B920B046-AC8E-4B85-A4BB-A81C1A235BA8}.Release|Any CPU.Build.0 = Release|Any CPU
44 | {69F6F354-3554-4014-828D-230BA5E2B234}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45 | {69F6F354-3554-4014-828D-230BA5E2B234}.Debug|Any CPU.Build.0 = Debug|Any CPU
46 | {69F6F354-3554-4014-828D-230BA5E2B234}.Release|Any CPU.ActiveCfg = Release|Any CPU
47 | {69F6F354-3554-4014-828D-230BA5E2B234}.Release|Any CPU.Build.0 = Release|Any CPU
48 | EndGlobalSection
49 | GlobalSection(SolutionProperties) = preSolution
50 | HideSolutionNode = FALSE
51 | EndGlobalSection
52 | GlobalSection(ExtensibilityGlobals) = postSolution
53 | SolutionGuid = {693A8AEA-287A-4F0F-983C-4546ED8D9AD7}
54 | EndGlobalSection
55 | EndGlobal
56 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/GameManager.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 |
3 | namespace Tetris
4 | {
5 | public class TetrisGameManager
6 | {
7 | private ITetrisGame tetrisGame;
8 | private IInputHandler consoleInputHandler;
9 | private TetrisConsoleWriter tetrisConsoleWriter;
10 | private ScoreManager scoreManager;
11 |
12 | public TetrisGameManager(ITetrisGame tetrisGame, IInputHandler consoleInputHandler, TetrisConsoleWriter tetrisConsoleWriter, ScoreManager scoreManager)
13 | {
14 | this.tetrisGame = tetrisGame;
15 | this.consoleInputHandler = consoleInputHandler;
16 | this.tetrisConsoleWriter = tetrisConsoleWriter;
17 | this.scoreManager = scoreManager;
18 | }
19 |
20 | public void MainLoop()
21 | {
22 | while (true)
23 | {
24 | tetrisConsoleWriter.Frame++;
25 | this.tetrisGame.UpdateLevel(scoreManager.Score);
26 | var input = this.consoleInputHandler.GetInput();
27 | switch (input)
28 | {
29 | case TetrisGameInput.Left:
30 | if (this.tetrisGame.CanMoveToLeft())
31 | {
32 | this.tetrisGame.CurrentFigureCol--;
33 | }
34 | break;
35 | case TetrisGameInput.Right:
36 | if (this.tetrisGame.CanMoveToRight())
37 | {
38 | this.tetrisGame.CurrentFigureCol++;
39 | }
40 | break;
41 | case TetrisGameInput.Down:
42 | tetrisConsoleWriter.Frame = 1;
43 | scoreManager.AddToScore(this.tetrisGame.Level, 0);
44 | this.tetrisGame.CurrentFigureRow++;
45 | break;
46 | case TetrisGameInput.Rotate:
47 | var newFigure = this.tetrisGame.CurrentFigure.GetRotate();
48 | if (!this.tetrisGame.Collision(newFigure))
49 | {
50 | this.tetrisGame.CurrentFigure = newFigure;
51 | }
52 | break;
53 | case TetrisGameInput.Exit:
54 | return;
55 | }
56 |
57 | // Update the game state
58 | if (tetrisConsoleWriter.Frame % (tetrisConsoleWriter.FramesToMoveFigure - this.tetrisGame.Level) == 0)
59 | {
60 | this.tetrisGame.CurrentFigureRow++;
61 | tetrisConsoleWriter.Frame = 0;
62 | }
63 |
64 | if (this.tetrisGame.Collision(this.tetrisGame.CurrentFigure))
65 | {
66 | this.tetrisGame.AddCurrentFigureToTetrisField();
67 | int lines = this.tetrisGame.CheckForFullLines();
68 | scoreManager.AddToScore(this.tetrisGame.Level, lines);
69 | this.tetrisGame.NewRandomFigure();
70 | if (this.tetrisGame.Collision(this.tetrisGame.CurrentFigure)) // game is over
71 | {
72 | scoreManager.AddToHighScore();
73 | tetrisConsoleWriter.DrawAll(this.tetrisGame, scoreManager);
74 | tetrisConsoleWriter.WriteGameOver(scoreManager.Score);
75 | Thread.Sleep(100000);
76 | return;
77 | }
78 | }
79 |
80 | // Redraw UI
81 | tetrisConsoleWriter.DrawAll(this.tetrisGame, scoreManager);
82 |
83 | Thread.Sleep(40);
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/Board.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace TicTacToe
6 | {
7 | public class Board : IBoard
8 | {
9 | private Symbol[,] board;
10 |
11 | public Board()
12 | : this(3, 3)
13 | {
14 | }
15 |
16 | public Board(int rows, int columns)
17 | {
18 | if (rows != columns)
19 | {
20 | throw new ArgumentException("Rows should be equal to columns");
21 | }
22 |
23 | Rows = rows;
24 | Columns = columns;
25 | board = new Symbol[rows, columns];
26 | }
27 |
28 | public int Rows { get; }
29 |
30 | public int Columns { get; }
31 |
32 | public Symbol[,] BoardState => this.board;
33 |
34 | public Symbol GetRowSymbol(int row)
35 | {
36 | var symbol = this.board[row, 0];
37 | if (symbol == Symbol.None)
38 | {
39 | return Symbol.None;
40 | }
41 |
42 | for (int col = 1; col < this.Columns; col++)
43 | {
44 | if (this.board[row, col] != symbol)
45 | {
46 | return Symbol.None;
47 | }
48 | }
49 |
50 | return symbol;
51 | }
52 |
53 | public Symbol GetColumnSymbol(int column)
54 | {
55 | var symbol = this.board[0, column];
56 | if (symbol == Symbol.None)
57 | {
58 | return Symbol.None;
59 | }
60 |
61 | for (int row = 1; row < this.Rows; row++)
62 | {
63 | if (this.board[row, column] != symbol)
64 | {
65 | return Symbol.None;
66 | }
67 | }
68 |
69 | return symbol;
70 | }
71 |
72 | public Symbol GetDiagonalTLBRSymbol()
73 | {
74 | var symbol = this.board[0, 0];
75 | if (symbol == Symbol.None)
76 | {
77 | return symbol;
78 | }
79 |
80 | for (int i = 1; i < this.Rows; i++)
81 | {
82 | if (this.board[i, i] != symbol)
83 | {
84 | return Symbol.None;
85 | }
86 | }
87 |
88 | return symbol;
89 | }
90 |
91 | public Symbol GetDiagonalTRBLSymbol()
92 | {
93 | var symbol = this.board[0, this.Rows - 1];
94 | if (symbol == Symbol.None)
95 | {
96 | return Symbol.None;
97 | }
98 |
99 | for (int row = 1; row < this.Rows; row++)
100 | {
101 | if (this.board[row, this.Rows - row - 1] != symbol)
102 | {
103 | return Symbol.None;
104 | }
105 | }
106 |
107 | return symbol;
108 | }
109 |
110 | public IEnumerable GetEmptyPositions()
111 | {
112 | var positions = new List();
113 | for (int i = 0; i < this.Rows; i++)
114 | {
115 | for (int j = 0; j < this.Columns; j++)
116 | {
117 | if (this.board[i, j] == Symbol.None)
118 | {
119 | positions.Add(new Index(i, j));
120 | }
121 | }
122 | }
123 |
124 | return positions;
125 | }
126 |
127 | public bool IsFull()
128 | {
129 | for (int i = 0; i < this.Rows; i++)
130 | {
131 | for (int j = 0; j < this.Columns; j++)
132 | {
133 | if (this.board[i, j] == Symbol.None)
134 | {
135 | return false;
136 | }
137 | }
138 | }
139 |
140 | return true;
141 | }
142 |
143 | public void PlaceSymbol(Index index, Symbol symbol)
144 | {
145 | if (index.Row < 0 || index.Column < 0
146 | || index.Row >= this.Rows || index.Column >= this.Columns)
147 | {
148 | throw new IndexOutOfRangeException("Index is out of range.");
149 | }
150 |
151 | this.board[index.Row, index.Column] = symbol;
152 | }
153 |
154 | public override string ToString()
155 | {
156 | var sb = new StringBuilder();
157 | for (int i = 0; i < this.Rows; i++)
158 | {
159 | for (int j = 0; j < this.Columns; j++)
160 | {
161 | if (this.board[i, j] == Symbol.None)
162 | {
163 | sb.Append('.');
164 | }
165 | else
166 | {
167 | sb.Append(this.board[i, j]);
168 | }
169 | }
170 |
171 | sb.AppendLine();
172 | }
173 |
174 | return sb.ToString();
175 | }
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/TicTacToe/TicTacToe/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using TicTacToe.Players;
3 |
4 | namespace TicTacToe
5 | {
6 | class Program
7 | {
8 | // TODO: Add test to verify that random never win vs AI
9 | // TODO: Write stats to a file and show it
10 | // TODO: Use simple factory for the Game class based on the user input
11 | static void Main(string[] args)
12 | {
13 | Console.Title = "TicTacToe 1.0";
14 | while (true)
15 | {
16 | Console.Clear();
17 | Console.WriteLine("==== TicTacToe 1.0 ====");
18 | Console.WriteLine("1. Player vs Player");
19 | Console.WriteLine("2. Player vs Random");
20 | Console.WriteLine("3. Random vs Player");
21 | Console.WriteLine("4. Player vs AI");
22 | Console.WriteLine("5. AI vs Player");
23 | Console.WriteLine("6. Simulate Random vs Random");
24 | Console.WriteLine("7. Simulate AI vs Random");
25 | Console.WriteLine("8. Simulate Random vs AI");
26 | Console.WriteLine("9. Simulate AI vs AI");
27 | Console.WriteLine("0. Exit");
28 |
29 | while (true)
30 | {
31 | Console.Write("Please enter number [0-9]: ");
32 | var line = Console.ReadLine();
33 | if (line == "0")
34 | {
35 | return;
36 | }
37 | if (line == "1")
38 | {
39 | PlayGame(new ConsolePlayer(), new ConsolePlayer());
40 | break;
41 | }
42 | if (line == "2")
43 | {
44 | PlayGame(new ConsolePlayer(), new RandomPlayer());
45 | break;
46 | }
47 | if (line == "3")
48 | {
49 | PlayGame(new RandomPlayer(), new ConsolePlayer());
50 | break;
51 | }
52 | if (line == "4")
53 | {
54 | PlayGame(new ConsolePlayer(), new AiPlayer());
55 | break;
56 | }
57 | if (line == "5")
58 | {
59 | PlayGame(new AiPlayer(), new ConsolePlayer());
60 | break;
61 | }
62 | if (line == "6")
63 | {
64 | Simulate(new RandomPlayer(), new RandomPlayer(), 10000);
65 | break;
66 | }
67 | if (line == "7")
68 | {
69 | Simulate(new AiPlayer(), new RandomPlayer(), 10);
70 | break;
71 | }
72 | if (line == "8")
73 | {
74 | Simulate(new RandomPlayer(), new AiPlayer(), 10);
75 | break;
76 | }
77 | if (line == "9")
78 | {
79 | Simulate(new AiPlayer(), new AiPlayer(), 10);
80 | break;
81 | }
82 | }
83 |
84 | Console.Write("Press [enter] to continue...");
85 | Console.ReadLine();
86 | }
87 | }
88 |
89 | static void Simulate(IPlayer player1, IPlayer player2, int count)
90 | {
91 | int x = 0, o = 0, draw = 0;
92 | int firstWinner = 0, secondWinner = 0;
93 | var first = player1;
94 | var second = player2;
95 | for (int i = 0; i < count; i++)
96 | {
97 | var game = new TicTacToeGame(first, second);
98 | var result = game.Play();
99 | if (result.Winner == Symbol.X && first == player1) firstWinner++;
100 | if (result.Winner == Symbol.O && first == player1) secondWinner++;
101 | if (result.Winner == Symbol.X && first == player2) secondWinner++;
102 | if (result.Winner == Symbol.O && first == player2) firstWinner++;
103 | if (result.Winner == Symbol.X) x++;
104 | if (result.Winner == Symbol.O) o++;
105 | if (result.Winner == Symbol.None) draw++;
106 | (first, second) = (second, first);
107 | }
108 |
109 | Console.WriteLine("Games played: " + count);
110 | Console.WriteLine("Games won by X: " + x);
111 | Console.WriteLine("Games won by O: " + o);
112 | Console.WriteLine("Draw games: " + draw);
113 | Console.WriteLine(player1.GetType().Name + " won games: " + firstWinner);
114 | Console.WriteLine(player2.GetType().Name + " won games: " + secondWinner);
115 | }
116 |
117 | static void PlayGame(IPlayer player1, IPlayer player2)
118 | {
119 | var game = new TicTacToeGame(player1, player2);
120 | var result = game.Play();
121 | Console.ForegroundColor = ConsoleColor.DarkRed;
122 | Console.WriteLine("Game over!");
123 | if (result.Winner == Symbol.None)
124 | {
125 | Console.WriteLine("Winner: Draw");
126 | }
127 | else
128 | {
129 | Console.WriteLine("Winner: " + result.Winner);
130 | }
131 |
132 | Console.WriteLine(result.Board.ToString());
133 | Console.ResetColor();
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/Tetris (.NET Core)/TetrisConsoleWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Tetris
4 | {
5 | public class TetrisConsoleWriter
6 | {
7 | private int tetrisRows;
8 | private int tetrisColumns;
9 | private int infoColumns;
10 | private int consoleRows;
11 | private int consoleColumns;
12 | private char tetrisCharacter;
13 |
14 | public TetrisConsoleWriter(
15 | int tetrisRows,
16 | int tetrisColumns,
17 | char tetrisCharacter = '*',
18 | int infoColumns = 11)
19 | {
20 | this.tetrisRows = tetrisRows;
21 | this.tetrisColumns = tetrisColumns;
22 | this.tetrisCharacter = tetrisCharacter;
23 | this.infoColumns = infoColumns;
24 | this.consoleRows = 1 + this.tetrisRows + 1;
25 | this.consoleColumns = 1 + this.tetrisColumns + 1 + this.infoColumns + 1;
26 |
27 | this.Frame = 0;
28 | this.FramesToMoveFigure = 15;
29 |
30 | Console.WindowHeight = this.consoleRows + 1;
31 | Console.WindowWidth = this.consoleColumns;
32 | Console.BufferHeight = this.consoleRows + 1;
33 | Console.BufferWidth = this.consoleColumns;
34 | Console.ForegroundColor = ConsoleColor.Black;
35 | Console.Title = "Tetris v1.0";
36 | Console.CursorVisible = false;
37 | }
38 |
39 | public int Frame { get; set; }
40 |
41 | public int FramesToMoveFigure { get; private set; }
42 |
43 | public void DrawAll(ITetrisGame state, ScoreManager scoreManager)
44 | {
45 | this.DrawBorder();
46 | this.DrawGameState(3 + this.tetrisColumns, state, scoreManager);
47 | this.DrawTetrisField(state.TetrisField);
48 | this.DrawCurrentFigure(state.CurrentFigure, state.CurrentFigureRow, state.CurrentFigureCol);
49 |
50 | }
51 |
52 | public void DrawGameState(int startColumn, ITetrisGame state, ScoreManager scoreManager)
53 | {
54 | this.Write("Level:", 1, startColumn);
55 | this.Write(state.Level.ToString(), 2, startColumn);
56 | this.Write("Score:", 4, startColumn);
57 | this.Write(scoreManager.Score.ToString(), 5, startColumn);
58 | this.Write("Best:", 7, startColumn);
59 | this.Write(scoreManager.HighScore.ToString(), 8, startColumn);
60 | this.Write("Frame:", 10, startColumn);
61 | this.Write(this.Frame.ToString() + " / " + (this.FramesToMoveFigure - state.Level).ToString(), 11, startColumn);
62 | this.Write("Position:", 13, startColumn);
63 | this.Write($"{state.CurrentFigureRow}, {state.CurrentFigureCol}", 14, startColumn);
64 | this.Write("Keys:", 16, startColumn);
65 | this.Write($" ^ ", 18, startColumn);
66 | this.Write($"< > ", 19, startColumn);
67 | this.Write($" v ", 20, startColumn);
68 | }
69 |
70 | public void DrawBorder()
71 | {
72 | Console.SetCursorPosition(0, 0);
73 | string line = "╔";
74 | line += new string('═', this.tetrisColumns);
75 | /* for (int i = 0; i < TetrisCols; i++)
76 | {
77 | line += "═";
78 | } */
79 |
80 | line += "╦";
81 | line += new string('═', this.infoColumns);
82 | line += "╗";
83 | Console.Write(line);
84 |
85 | for (int i = 0; i < this.tetrisRows; i++)
86 | {
87 | string middleLine = "║";
88 | middleLine += new string(' ', this.tetrisColumns);
89 | middleLine += "║";
90 | middleLine += new string(' ', this.infoColumns);
91 | middleLine += "║";
92 | Console.Write(middleLine);
93 | }
94 |
95 | string endLine = "╚";
96 | endLine += new string('═', this.tetrisColumns);
97 | endLine += "╩";
98 | endLine += new string('═', this.infoColumns);
99 | endLine += "╝";
100 | Console.Write(endLine);
101 | }
102 |
103 | public void WriteGameOver(int score)
104 | {
105 | int row = this.tetrisRows / 2 - 3;
106 | int column = (this.tetrisColumns + 3 + this.infoColumns) / 2 - 6;
107 |
108 | var scoreAsString = score.ToString();
109 | scoreAsString = new string(' ', 7 - scoreAsString.Length) + scoreAsString;
110 | Write("╔═════════╗", row, column);
111 | Write("║ Game ║", row + 1, column);
112 | Write("║ over! ║", row + 2, column);
113 | Write($"║ {scoreAsString} ║", row + 3, column);
114 | Write("╚═════════╝", row + 4, column);
115 | }
116 |
117 | public void DrawTetrisField(bool[,] tetrisField)
118 | {
119 | for (int row = 0; row < tetrisField.GetLength(0); row++)
120 | {
121 | string line = "";
122 | for (int col = 0; col < tetrisField.GetLength(1); col++)
123 | {
124 | if (tetrisField[row, col])
125 | {
126 | line += tetrisCharacter;
127 | }
128 | else
129 | {
130 | line += " ";
131 | }
132 | }
133 |
134 | this.Write(line, row + 1, 1);
135 | }
136 | }
137 |
138 | public void DrawCurrentFigure(Tetromino currentFigure, int currentFigureRow, int currentFigureColumn)
139 | {
140 | for (int row = 0; row < currentFigure.Width; row++)
141 | {
142 | for (int col = 0; col < currentFigure.Height; col++)
143 | {
144 | if (currentFigure.Body[row, col])
145 | {
146 | Write(tetrisCharacter.ToString(), row + 1 + currentFigureRow, 1 + currentFigureColumn + col);
147 | }
148 | }
149 | }
150 | }
151 |
152 | private void Write(string text, int row, int col)
153 | {
154 | Console.SetCursorPosition(col, row);
155 | Console.Write(text);
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/Cars/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 |
7 | struct Object
8 | {
9 | public int x;
10 | public int y;
11 | public char c;
12 | public ConsoleColor color;
13 | }
14 |
15 | class Program
16 | {
17 | static void PrintOnPosition(int x, int y, char c,
18 | ConsoleColor color = ConsoleColor.Gray)
19 | {
20 | Console.SetCursorPosition(x, y);
21 | Console.ForegroundColor = color;
22 | Console.Write(c);
23 | }
24 | static void PrintStringOnPosition(int x, int y, string str,
25 | ConsoleColor color = ConsoleColor.Gray)
26 | {
27 | Console.SetCursorPosition(x, y);
28 | Console.ForegroundColor = color;
29 | Console.Write(str);
30 | }
31 | static void Main()
32 | {
33 | double speed = 100.0;
34 | double acceleration = 0.5;
35 | int playfieldWidth = 5;
36 | int livesCount = 5;
37 | Console.BufferHeight = Console.WindowHeight = 20;
38 | Console.BufferWidth = Console.WindowWidth = 30;
39 | Object userCar = new Object();
40 | userCar.x = 2;
41 | userCar.y = Console.WindowHeight - 1;
42 | userCar.c = '@';
43 | userCar.color = ConsoleColor.Yellow;
44 | Random randomGenerator = new Random();
45 | List