diff --git a/pac-man-board-game/ClientApp/src/AppRoutes.tsx b/pac-man-board-game/ClientApp/src/AppRoutes.tsx
index dbb2f04..d304c32 100644
--- a/pac-man-board-game/ClientApp/src/AppRoutes.tsx
+++ b/pac-man-board-game/ClientApp/src/AppRoutes.tsx
@@ -1,7 +1,6 @@
 import React from "react";
 import {Counter} from "./pages/Counter";
-import {FetchData} from "./pages/FetchData";
-import {Home} from "./pages/Home";
+import Home from "./pages/home";
 
 const AppRoutes = [
   {
@@ -12,10 +11,6 @@ const AppRoutes = [
     path: "/counter",
     element: <Counter/>
   },
-  {
-    path: "/fetch-data",
-    element: <FetchData/>
-  }
 ];
 
 export default AppRoutes;
diff --git a/pac-man-board-game/ClientApp/src/classes/WebSocketService.ts b/pac-man-board-game/ClientApp/src/classes/WebSocketService.ts
index 4a0c8ba..5335b45 100644
--- a/pac-man-board-game/ClientApp/src/classes/WebSocketService.ts
+++ b/pac-man-board-game/ClientApp/src/classes/WebSocketService.ts
@@ -1,6 +1,3 @@
-type VoidFunction = () => void;
-type MessageEventFunction = (data: MessageEvent<any>) => void;
-
 interface IWebSocket {
   onOpen?: VoidFunction,
   onReceive?: MessageEventFunction,
diff --git a/pac-man-board-game/ClientApp/src/components/NavMenu.tsx b/pac-man-board-game/ClientApp/src/components/NavMenu.tsx
index 0d0a75c..18ee88c 100644
--- a/pac-man-board-game/ClientApp/src/components/NavMenu.tsx
+++ b/pac-man-board-game/ClientApp/src/components/NavMenu.tsx
@@ -18,7 +18,6 @@ export const NavMenu = () => {
                     <ul className="navbar-nav flex-grow">
                             <Link className="text-dark" to="/">Home</Link>
                             <Link className="text-dark" to="/counter">Counter</Link>
-                            <Link className="text-dark" to="/fetch-data">Fetch data</Link>
                     </ul>
                 </div>
             </nav>
diff --git a/pac-man-board-game/ClientApp/src/components/gameCanvas.tsx b/pac-man-board-game/ClientApp/src/components/gameCanvas.tsx
new file mode 100644
index 0000000..69289eb
--- /dev/null
+++ b/pac-man-board-game/ClientApp/src/components/gameCanvas.tsx
@@ -0,0 +1,22 @@
+import React from "react";
+import TileMap from "../game/tileMap";
+
+const tileMap = new TileMap();
+
+const GameCanvas: Component = ({className}) => {
+
+  const canvasRef = React.useRef<HTMLCanvasElement>(null);
+
+  React.useEffect(() => {
+    const context = canvasRef.current?.getContext("2d");
+    if (!context) return;
+
+    tileMap.draw(context);
+  }, []);
+
+  return (
+    <canvas ref={canvasRef} className={`shadow-lg w-3/4 aspect-square ${className}`}></canvas>
+  );
+};
+
+export default GameCanvas;
diff --git a/pac-man-board-game/ClientApp/src/components/gameComponent.tsx b/pac-man-board-game/ClientApp/src/components/gameComponent.tsx
new file mode 100644
index 0000000..92017ea
--- /dev/null
+++ b/pac-man-board-game/ClientApp/src/components/gameComponent.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+import GameCanvas from "../components/gameCanvas";
+import Game from "../game/game";
+
+export const GameComponent: Component = () => {
+
+  React.useEffect(() => {
+    const game = new Game();
+    const id = setInterval(game.gameLoop, 1000);
+    return () => clearInterval(id);
+  }, []);
+
+  return (
+    <div>
+      <h1 className={"w-fit mx-auto"}>Pac-Man</h1>
+      <GameCanvas className={"mx-auto"}/>
+    </div>
+  );
+};
diff --git a/pac-man-board-game/ClientApp/src/game/game.ts b/pac-man-board-game/ClientApp/src/game/game.ts
new file mode 100644
index 0000000..071dc90
--- /dev/null
+++ b/pac-man-board-game/ClientApp/src/game/game.ts
@@ -0,0 +1,65 @@
+export default class Game {
+
+  constructor() {
+    // Connect to the server
+
+    // Create players
+
+    // Pick player pieces
+
+    // Roll to start
+  }
+
+  public gameLoop(): void {
+    // Throw the dices
+
+    // Choose a dice and move pac-man or a ghost
+
+    // Use the remaining dice to move pac-man if the player moved a ghost or vice versa
+
+    // Check if the game is over
+
+    // If not, next player
+  }
+
+  private connectToServer(): void {
+    throw new Error("Not implemented");
+  }
+
+  private createPlayers(): void {
+    throw new Error("Not implemented");
+  }
+
+  private pickPlayerPieces(): void {
+    throw new Error("Not implemented");
+  }
+
+  private rollToStart(): void {
+    throw new Error("Not implemented");
+  }
+
+  private throwDices(): number[] {
+    throw new Error("Not implemented");
+  }
+
+  private chooseDice(dices: number[]): number {
+    throw new Error("Not implemented");
+  }
+
+  private movePacMan(dice: number): void {
+    throw new Error("Not implemented");
+  }
+
+  private moveGhost(dice: number): void {
+    throw new Error("Not implemented");
+  }
+
+  private isGameOver(): boolean {
+    throw new Error("Not implemented");
+  }
+
+  private nextPlayer(): void {
+    throw new Error("Not implemented");
+  }
+
+}
\ No newline at end of file
diff --git a/pac-man-board-game/ClientApp/src/game/tileMap.ts b/pac-man-board-game/ClientApp/src/game/tileMap.ts
new file mode 100644
index 0000000..3f50e1c
--- /dev/null
+++ b/pac-man-board-game/ClientApp/src/game/tileMap.ts
@@ -0,0 +1,68 @@
+export default class TileMap {
+
+  /**
+   * 0 = empty
+   * 1 = wall
+   * 2 = pellet
+   * 3 = power pellet
+   * 4 = ghost spawn
+   * 5 = pacman spawn
+   */
+  private map: number[][] = [
+    [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
+    [1, 2, 0, 0, 0, 2, 0, 0, 0, 2, 1],
+    [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
+    [1, 0, 1, 5, 1, 0, 1, 4, 1, 0, 1],
+    [1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1],
+    [0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0],
+    [1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1],
+    [1, 0, 1, 4, 1, 0, 1, 5, 1, 0, 1],
+    [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
+    [1, 2, 0, 0, 0, 2, 0, 0, 0, 2, 1],
+    [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
+  ];
+
+  public draw(ctx: CanvasRenderingContext2D): void {
+    this.drawMap(ctx);
+  }
+
+  private drawMap(context: CanvasRenderingContext2D): void {
+    const tileSize = this.getTileSize(context);
+
+    for (let row = 0; row < this.map.length; row++) {
+      for (let col = 0; col < this.map[row].length; col++) {
+
+        const tile = this.map[row][col];
+        switch (tile) {
+          case 0:
+            this.drawTile(context, col * tileSize, row * tileSize, tileSize, "black");
+            break;
+          case 1:
+            this.drawTile(context, col * tileSize, row * tileSize, tileSize, "blue");
+            break;
+          case 2:
+            this.drawTile(context, col * tileSize, row * tileSize, tileSize, "yellow");
+            break;
+          case 3:
+            this.drawTile(context, col * tileSize, row * tileSize, tileSize, "orange");
+            break;
+          case 4:
+            this.drawTile(context, col * tileSize, row * tileSize, tileSize, "red");
+            break;
+        }
+
+      }
+    }
+  }
+
+  private drawTile(context: CanvasRenderingContext2D, x: number, y: number, tileSize: number, color: string): void {
+    context.fillStyle = color;
+    context.fillRect(x, y, tileSize, tileSize);
+  }
+
+  private getTileSize(context: CanvasRenderingContext2D): number {
+    const canvasSize = context.canvas.width;
+    context.canvas.height = canvasSize;
+    return canvasSize / this.map[0].length;
+  }
+}
diff --git a/pac-man-board-game/ClientApp/src/pages/Counter.tsx b/pac-man-board-game/ClientApp/src/pages/Counter.tsx
index d582b8b..dd8dbfd 100644
--- a/pac-man-board-game/ClientApp/src/pages/Counter.tsx
+++ b/pac-man-board-game/ClientApp/src/pages/Counter.tsx
@@ -5,7 +5,6 @@ const ws = new WebSocketService({});
 
 export const Counter: Component = () => {
 
-  ws.onReceive = receiveMessage;
   const [currentCount, setCurrentCount] = React.useState(0);
 
   function incrementCounterAndSend() {
@@ -21,6 +20,7 @@ export const Counter: Component = () => {
   }
 
   React.useEffect(() => {
+    ws.onReceive = receiveMessage;
     ws.open();
     return () => {
       ws.close();
diff --git a/pac-man-board-game/ClientApp/src/pages/FetchData.tsx b/pac-man-board-game/ClientApp/src/pages/FetchData.tsx
deleted file mode 100644
index 72a8ef1..0000000
--- a/pac-man-board-game/ClientApp/src/pages/FetchData.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from "react";
-
-export const FetchData: Component = () => {
-
-  const [forecasts, setForecasts] = React.useState<any>([]);
-  const [loading, setLoading] = React.useState(true);
-
-  async function populateWeatherData() {
-    const response = await fetch("api/WeatherForecast");
-    const data = await response.json();
-    setForecasts(data);
-    setLoading(false);
-  }
-
-  React.useEffect(() => {
-    populateWeatherData().then(null);
-  }, []);
-
-  return <>
-    {
-      loading ?
-        <p><em>Loading...</em></p> :
-        <table className="table table-striped" aria-labelledby="tableLabel">
-          <thead>
-          <tr>
-            <th>Date</th>
-            <th>Temp. (C)</th>
-            <th>Temp. (F)</th>
-            <th>Summary</th>
-          </tr>
-          </thead>
-          <tbody>
-          {forecasts.map((forecast: any) =>
-            <tr key={forecast.date}>
-              <td>{forecast.date}</td>
-              <td>{forecast.temperatureC}</td>
-              <td>{forecast.temperatureF}</td>
-              <td>{forecast.summary}</td>
-            </tr>
-          )}
-          </tbody>
-        </table>
-
-    }</>;
-};
diff --git a/pac-man-board-game/ClientApp/src/pages/Home.tsx b/pac-man-board-game/ClientApp/src/pages/Home.tsx
deleted file mode 100644
index 133c4da..0000000
--- a/pac-man-board-game/ClientApp/src/pages/Home.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React from "react";
-
-export const Home: Component = () => (
-  <div>
-    <h1 className={"debug w-fit"}>Hello, world!</h1>
-    <p className={"text-cyan-900"}>Welcome to your new single-page application, built with:</p>
-    <ul>
-      <li><a href="https://get.asp.net/">ASP.NET Core</a> and <a
-        href="https://msdn.microsoft.com/en-us/library/67ef8sbd.aspx">C#</a> for cross-platform server-side
-        code
-      </li>
-      <li><a href="https://facebook.github.io/react/">React</a> for client-side code</li>
-    </ul>
-    <p>To help you get started, we have also set up:</p>
-    <ul>
-      <li><strong>Client-side navigation</strong>. For example, click <em>Counter</em> then <em>Back</em> to
-        return here.
-      </li>
-      <li><strong>Development server integration</strong>. In development mode, the development server
-        from <code>create-react-app</code> runs in the background automatically, so your client-side
-        resources are dynamically built on demand and the page refreshes when you modify any file.
-      </li>
-      <li><strong>Efficient production builds</strong>. In production mode, development-time features are
-        disabled, and your <code>dotnet publish</code> configuration produces minified, efficiently bundled
-        JavaScript files.
-      </li>
-    </ul>
-    <p>The <code>ClientApp</code> subdirectory is a standard React application based on
-      the <code>create-react-app</code> template. If you open a command prompt in that directory, you can
-      run <code>npm</code> commands such as <code>npm test</code> or <code>npm install</code>.</p>
-  </div>
-);
diff --git a/pac-man-board-game/ClientApp/src/pages/home.tsx b/pac-man-board-game/ClientApp/src/pages/home.tsx
new file mode 100644
index 0000000..ec521b2
--- /dev/null
+++ b/pac-man-board-game/ClientApp/src/pages/home.tsx
@@ -0,0 +1,10 @@
+import React from "react";
+import {GameComponent} from "../components/gameComponent";
+
+const Home: Component = () => (
+  <div>
+    <GameComponent/>
+  </div>
+);
+
+export default Home;
\ No newline at end of file
diff --git a/pac-man-board-game/ClientApp/src/types/props.d.ts b/pac-man-board-game/ClientApp/src/types/props.d.ts
index 9c8635a..5498d64 100644
--- a/pac-man-board-game/ClientApp/src/types/props.d.ts
+++ b/pac-man-board-game/ClientApp/src/types/props.d.ts
@@ -1,5 +1,3 @@
-type Setter<T> = React.Dispatch<React.SetStateAction<T>>;
-
 type Component<T = ComponentProps> = (props: T) => React.JSX.Element;
 
 interface ComponentProps {
diff --git a/pac-man-board-game/ClientApp/src/types/types.d.ts b/pac-man-board-game/ClientApp/src/types/types.d.ts
new file mode 100644
index 0000000..e283ea2
--- /dev/null
+++ b/pac-man-board-game/ClientApp/src/types/types.d.ts
@@ -0,0 +1,3 @@
+type MessageEventFunction = (data: MessageEvent<any>) => void;
+
+type Setter<T> = React.Dispatch<React.SetStateAction<T>>;
diff --git a/pac-man-board-game/Game/Interfaces/IBox.cs b/pac-man-board-game/Game/Interfaces/IBox.cs
new file mode 100644
index 0000000..e21f934
--- /dev/null
+++ b/pac-man-board-game/Game/Interfaces/IBox.cs
@@ -0,0 +1,6 @@
+namespace pacMan.Game.Interfaces;
+
+public interface IBox : IEnumerable<IOrb>
+{
+    void Add(IOrb orb);
+}
\ No newline at end of file
diff --git a/pac-man-board-game/Game/Interfaces/IDice.cs b/pac-man-board-game/Game/Interfaces/IDice.cs
new file mode 100644
index 0000000..6d28586
--- /dev/null
+++ b/pac-man-board-game/Game/Interfaces/IDice.cs
@@ -0,0 +1,6 @@
+namespace pacMan.Game.Interfaces;
+
+public interface IDice
+{
+    int Roll();
+}
\ No newline at end of file
diff --git a/pac-man-board-game/Game/Interfaces/IDiceCup.cs b/pac-man-board-game/Game/Interfaces/IDiceCup.cs
new file mode 100644
index 0000000..ef2a280
--- /dev/null
+++ b/pac-man-board-game/Game/Interfaces/IDiceCup.cs
@@ -0,0 +1,6 @@
+namespace pacMan.Game.Interfaces;
+
+public interface IDiceCup
+{
+    List<int> Roll();
+}
\ No newline at end of file
diff --git a/pac-man-board-game/Game/Interfaces/IOrb.cs b/pac-man-board-game/Game/Interfaces/IOrb.cs
new file mode 100644
index 0000000..8b1a372
--- /dev/null
+++ b/pac-man-board-game/Game/Interfaces/IOrb.cs
@@ -0,0 +1,6 @@
+namespace pacMan.Game.Interfaces;
+
+public interface IOrb
+{
+    void Use();
+}
\ No newline at end of file
diff --git a/pac-man-board-game/Game/Items/Dice.cs b/pac-man-board-game/Game/Items/Dice.cs
new file mode 100644
index 0000000..3da4092
--- /dev/null
+++ b/pac-man-board-game/Game/Items/Dice.cs
@@ -0,0 +1,10 @@
+using pacMan.Game.Interfaces;
+
+namespace pacMan.Game.Items;
+
+public class Dice : IDice
+{
+    private readonly Random _random = new();
+    
+    public int Roll() => _random.Next(1, 7);
+}
\ No newline at end of file
diff --git a/pac-man-board-game/Game/Items/DiceCup.cs b/pac-man-board-game/Game/Items/DiceCup.cs
new file mode 100644
index 0000000..f611456
--- /dev/null
+++ b/pac-man-board-game/Game/Items/DiceCup.cs
@@ -0,0 +1,19 @@
+using pacMan.Game.Interfaces;
+
+namespace pacMan.Game.Items;
+
+public class DiceCup : IDiceCup
+{
+    private readonly List<Dice> _dices;
+
+    public DiceCup()
+    {
+        _dices = new List<Dice>
+        {
+            new(),
+            new()
+        };
+    }
+
+    public List<int> Roll() => _dices.Select(d => d.Roll()).ToList();
+}
\ No newline at end of file
diff --git a/pac-man-board-game/Game/Rules.cs b/pac-man-board-game/Game/Rules.cs
new file mode 100644
index 0000000..3a4e7ae
--- /dev/null
+++ b/pac-man-board-game/Game/Rules.cs
@@ -0,0 +1,9 @@
+namespace pacMan.Game;
+
+public class Rules
+{
+    public const int MinPlayers = 2;
+    public const int MaxPlayers = 4;
+    public const int NumGhosts = 2;
+    public const int BoardSize = 10;
+}
\ No newline at end of file
diff --git a/pac-man-board-game/Interfaces/IWebSocketService.cs b/pac-man-board-game/Interfaces/IWebSocketService.cs
index 67ccb0a..afa3237 100644
--- a/pac-man-board-game/Interfaces/IWebSocketService.cs
+++ b/pac-man-board-game/Interfaces/IWebSocketService.cs
@@ -5,11 +5,12 @@ namespace pacMan.Interfaces;
 public interface IWebSocketService
 {
     void Add(WebSocket webSocket);
-    void Remove(WebSocket webSocket);
+    bool Remove(WebSocket webSocket);
     Task Send(WebSocket webSocket, string message, int length);
     Task Send(WebSocket webSocket, byte[] message, int length);
     Task SendToAll(string message, int length);
     Task SendToAll(byte[] message, int length);
     Task<WebSocketReceiveResult> Receive(WebSocket webSocket, byte[] buffer);
     Task Close(WebSocket webSocket, WebSocketCloseStatus closeStatus, string closeStatusDescription);
+    int CountConnected();
 }
\ No newline at end of file
diff --git a/pac-man-board-game/Services/WebSocketService.cs b/pac-man-board-game/Services/WebSocketService.cs
index 9568854..5ed71e4 100644
--- a/pac-man-board-game/Services/WebSocketService.cs
+++ b/pac-man-board-game/Services/WebSocketService.cs
@@ -1,3 +1,4 @@
+using System.Collections.Concurrent;
 using System.Net.WebSockets;
 using System.Text;
 using pacMan.Interfaces;
@@ -8,7 +9,7 @@ namespace pacMan.Services;
 public class WebSocketService : IWebSocketService
 {
     private readonly ILogger<WebSocketService> _logger;
-    private readonly List<WebSocket> _webSockets = new();
+    private readonly BlockingCollection<WebSocket> _webSockets = new();
 
     public WebSocketService(ILogger<WebSocketService> logger)
     {
@@ -19,13 +20,14 @@ public class WebSocketService : IWebSocketService
     public void Add(WebSocket webSocket)
     {
         _webSockets.Add(webSocket);
-        _logger.Log(LogLevel.Debug, "WebSocket \"{}\" added to list", webSocket.GetHashCode());
+        _logger.Log(LogLevel.Debug, "WebSocket added to list");
     }
 
-    public void Remove(WebSocket webSocket)
+    public bool Remove(WebSocket? webSocket)
     {
-        _webSockets.Remove(webSocket);
-        _logger.Log(LogLevel.Debug, "WebSocket \"{}\" removed from list", webSocket.GetHashCode());
+        var taken = _webSockets.TryTake(out webSocket);
+        _logger.Log(LogLevel.Debug, "WebSocket removed from list");
+        return taken;
     }
 
     public async Task Send(WebSocket webSocket, string message, int length)
@@ -44,9 +46,8 @@ public class WebSocketService : IWebSocketService
             CancellationToken.None);
         
         _logger.Log(LogLevel.Trace,
-            "Message \"{}\" sent to WebSocket {}",
-            message.GetString(length),
-            webSocket.GetHashCode());
+            "Message \"{}\" sent to WebSocket",
+            message.GetString(length));
     }
 
     public async Task SendToAll(string message, int length)
@@ -66,9 +67,8 @@ public class WebSocketService : IWebSocketService
     {
         var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
         _logger.Log(LogLevel.Debug,
-            "Message \"{}\" received from WebSocket {}",
-            buffer.GetString(result.Count),
-            webSocket.GetHashCode());
+            "Message \"{}\" received from WebSocket",
+            buffer.GetString(result.Count));
         return result;
     }
 
@@ -79,6 +79,8 @@ public class WebSocketService : IWebSocketService
             closeStatus,
             closeStatusDescription,
             CancellationToken.None);
-        _logger.Log(LogLevel.Information, "WebSocket connection closed from {}", webSocket.GetHashCode());
+        _logger.Log(LogLevel.Information, "WebSocket connection closed");
     }
+    
+    public int CountConnected() => _webSockets.Count;
 }
\ No newline at end of file
diff --git a/pac-man-board-game/pac-man-board-game.csproj b/pac-man-board-game/pac-man-board-game.csproj
index 75f66ac..f286054 100644
--- a/pac-man-board-game/pac-man-board-game.csproj
+++ b/pac-man-board-game/pac-man-board-game.csproj
@@ -33,6 +33,8 @@
       <TypeScriptCompile Remove="ClientApp\src\components\Counter.tsx" />
       <TypeScriptCompile Remove="ClientApp\src\components\FetchData.tsx" />
       <TypeScriptCompile Remove="ClientApp\src\components\Home.tsx" />
+      <TypeScriptCompile Remove="ClientApp\src\pages\FetchData.tsx" />
+      <TypeScriptCompile Remove="ClientApp\src\classes\tileMap.ts" />
     </ItemGroup>
 
     <Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">