diff --git a/templates/_folder_Lectures/O12 - handout Pong/Pong.cpp b/templates/_folder_Lectures/O12 - handout Pong/Pong.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e1b42d47124f20f4aa1cc901c4b539ea07899cd6
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Pong/Pong.cpp	
@@ -0,0 +1,35 @@
+#include "Pong.h"
+
+
+bool isBetween(int x, int lower, int upper) {
+    return (x >= lower) && (x <= upper);
+}
+
+void Racket::moveDown() {
+   
+}
+
+void Racket::moveUp() {
+    
+}
+
+void Ball::move() {
+
+}
+
+int Ball::nextX() { 
+    return position.x + ((int) dirX)*velocity;
+}
+int Ball::nextY() {
+    return position.y + ((int) dirY)*velocity;
+}
+
+
+std::vector<double> Ball::calculateDirection(Racket racket) {
+    
+} 
+
+void Ball::setDirection(std::vector<double> nextDir) {
+    
+}
+
diff --git a/templates/_folder_Lectures/O12 - handout Pong/Pong.h b/templates/_folder_Lectures/O12 - handout Pong/Pong.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6a08bdbf6ad4f648fa9fc9ba2ce2a822d34dc52
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Pong/Pong.h	
@@ -0,0 +1,47 @@
+#pragma once
+#include "Point.h"
+#include <vector>
+
+bool isBetween(int x, int lower, int upper);
+
+class Racket {
+    private:
+        TDT4102::Point position;
+        static constexpr int velocity = 8;
+    public:
+        static constexpr int length = 4;
+        static constexpr int blockSize = 10;
+        
+        Racket() {}
+        Racket(TDT4102::Point initPos) : position{initPos} {}
+        TDT4102::Point getPosition() const { return position; };
+        int getX() const { return position.x; }
+        int getY() const { return position.y; }
+        void moveUp();
+        void moveDown();
+};
+
+class Ball {
+    private:
+        static constexpr int velocity = 8;
+        static constexpr int blockSize = Racket::blockSize;
+        TDT4102::Point position;
+    
+    public:
+        double dirX = 0;
+        double dirY = 0; 
+        Ball() {}
+        Ball(TDT4102::Point initPos, double x, double y) : position{initPos}, dirX{x}, dirY{y} {}
+        TDT4102::Point getPosition() const { return position; }
+        int getDir() const {
+            return dirX >= 0 ? 1 : -1;
+        }
+        int getX() const { return position.x; }
+        int getY() const { return position.y; }
+        int nextX();
+        int nextY();
+        std::vector<double> calculateDirection(Racket racket);
+        void setDirection(std::vector<double> nextDir);
+        void move(); 
+
+};
\ No newline at end of file
diff --git a/templates/_folder_Lectures/O12 - handout Pong/PongWindow.cpp b/templates/_folder_Lectures/O12 - handout Pong/PongWindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c507e94f33f2cba65a6312072a7fbf89ad868a3
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Pong/PongWindow.cpp	
@@ -0,0 +1,49 @@
+#include "PongWindow.h"
+
+
+PongWindow::PongWindow() {}
+
+void PongWindow::run() {
+
+    while(!should_close()) {
+
+    }
+}
+
+void PongWindow::drawPlayers() {
+
+}
+
+void PongWindow::drawBall() {
+
+}
+
+
+void PongWindow::handleCollision() {
+
+    //sjekk om ballen har kollidert med venstre racket
+    
+    //sjekk om ballen har kollidert med høyre racket
+    
+    //sjekker om ballen har kollidert med taket.
+    
+    //sjekker om ballen har kollidert med veggen til høyre eller venstre side, og gir poeng
+    //til riktig person dersom den har det.
+       
+
+}
+
+//håndterer input fra spillere. racketen kan ikke flytte seg utenfor vinduet.
+void PongWindow::handleInput() {
+    bool WKeyPressed = is_key_down(KeyboardKey::W);
+    bool SKeyPressed = is_key_down(KeyboardKey::S);
+    bool UpKeyPressed = is_key_down(KeyboardKey::UP);
+    bool DownKeyPressed = is_key_down(KeyboardKey::DOWN);
+
+    // flytt racketene opp og ned
+}
+
+void PongWindow::startGame() {
+    isGamePaused = false;
+    startBtn.setVisible(false);
+}
\ No newline at end of file
diff --git a/templates/_folder_Lectures/O12 - handout Pong/PongWindow.h b/templates/_folder_Lectures/O12 - handout Pong/PongWindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..52e8b259ccb621e109b777c786c48be964d1bbe0
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Pong/PongWindow.h	
@@ -0,0 +1,48 @@
+#pragma once
+#include "AnimationWindow.h"
+#include "widgets/Button.h"
+#include "widgets/TextInput.h"
+#include "Pong.h"
+
+class PongWindow: public TDT4102::AnimationWindow {
+
+public:
+    PongWindow();
+    void run();
+
+private:
+
+    //height and width of window in blocks.
+    static constexpr int pongGridWidth  = 50;
+    static constexpr int pongGridHeight = 30;
+
+    static constexpr int blockSize = 10;
+    static constexpr int racketLength = Racket::length*blockSize;
+
+    static constexpr int windowHeight = pongGridHeight*blockSize;
+    static constexpr int windowWidth = pongGridWidth*blockSize;
+
+    bool isGamePaused = true;
+
+    Racket playerLeft;
+    Racket playerRight;
+    Ball ball;
+
+    unsigned int playerLeftScore = 0;
+    unsigned int playerRightScore = 0;
+
+
+    void handleInput();
+    void drawBall();
+    void drawPlayers();
+    void handleCollision();
+
+    TDT4102::Button startBtn;
+    TDT4102::TextInput showPlayerLeftScore;
+    TDT4102::TextInput showPlayerRightScore;
+
+    void cb_start() { this->startGame(); }
+
+    void startGame();
+
+};
\ No newline at end of file
diff --git a/templates/_folder_Lectures/O12 - handout Pong/main.cpp b/templates/_folder_Lectures/O12 - handout Pong/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..42f5fef64374db0c8731ac7a8966d8619fd1365e
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Pong/main.cpp	
@@ -0,0 +1,8 @@
+#include "PongWindow.h"
+
+int main() {
+	PongWindow pw;
+	pw.run();
+
+	return 0;
+}
diff --git a/templates/_folder_Lectures/O12 - handout Snake/GameWindow.cpp b/templates/_folder_Lectures/O12 - handout Snake/GameWindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f70a85c1eb6e6b8df4747a3065accc7b16783e47
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Snake/GameWindow.cpp	
@@ -0,0 +1,97 @@
+#include "GameWindow.h"
+
+
+void GameWindow::drawSnake() {
+    /*
+        Draws the snake vector in the game window
+    */
+
+   // FILL INN CODE 
+
+}
+
+void GameWindow::run() {
+    /*
+        Main function, runs the game window
+        Handles the game logic: is game lost? is food eaten? 
+        Waits for keyboeard input and handles input 
+    */
+
+   // FILL IN CODE HERE 
+
+}
+
+
+
+
+TDT4102::Point GameWindow::nextPoint(Direction dir) {
+    /*
+        Find the next point in grid for the snake head, 
+        based on keyboard input
+    */
+    TDT4102::Point head = snake.getHead();
+    switch (dir) {
+        case Direction::RIGHT:
+            head.x += 1;
+            break;
+        case Direction::UP:
+            head.y -= 1;
+            break;
+        case Direction::LEFT:
+            head.x -= 1;
+            break;
+        case Direction::DOWN:
+            head.y += 1;
+            break;
+    }
+    return head;
+}
+
+bool GameWindow::gameLost(Direction dir){
+    /*
+        Check is the snake has crashed with the game window boundaries
+        or itself
+    */
+
+   // FILL INN CODE HERE
+
+
+}
+
+
+void GameWindow::sampleFood() {
+    /*
+
+        Finds a random coordinate in grid for the food block 
+        Makes sure that the food is not placed on top on the snake itself
+
+    */
+    std::uniform_int_distribution<int> uniW(0, gridWidth-1);
+    std::uniform_int_distribution<int> uniH(0, gridHeight-1);
+    std::vector<TDT4102::Point> snakeVec = snake.getSnake();
+    do {
+        food = TDT4102::Point{uniW(foodRandomEngine), uniH(foodRandomEngine)};        // Create a random coordinate
+    }
+    while (isFoodOnSnake());     // Check if it is on snake
+}
+
+bool GameWindow::isFoodOnSnake() {
+    std::vector<TDT4102::Point> snakeVec = snake.getSnake();
+    for (const TDT4102::Point& part : snakeVec) {
+        if (part == food) {
+            return true;
+        }
+    }
+    return false;
+} 
+
+bool GameWindow::hasSnakeCrashed(Direction dir) {
+    TDT4102::Point nextHead = nextPoint(dir);
+    std::vector<TDT4102::Point> snakeVec = snake.getSnake();
+    for (const TDT4102::Point& part : snakeVec) {
+        if (nextHead == part) {
+            return true;
+        }
+    }
+    return false;
+}
\ No newline at end of file
diff --git a/templates/_folder_Lectures/O12 - handout Snake/GameWindow.h b/templates/_folder_Lectures/O12 - handout Snake/GameWindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..adbfe521a6b55fbe98d4faf9082693a42c57142e
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Snake/GameWindow.h	
@@ -0,0 +1,43 @@
+#include "AnimationWindow.h"
+#include "Snake.h"
+#include <random>
+#include <chrono>
+
+
+enum class Direction {RIGHT, UP, LEFT, DOWN};           
+
+class GameWindow : public TDT4102::AnimationWindow {
+    private:
+        // ---------------- Game window parameters ----------------------------------- //
+        /*
+                TO-DO: Initialize the parameters for the game window and the grid 
+        */
+
+        // ---------------- Game window parameters ----------------------------------- //
+
+        static constexpr int gridWidth = 20;         
+        static constexpr int gridHeight = 20;
+        static constexpr int blockSize = 30;
+
+        Snake snake;                                        // Vector to represent the snake                                           
+        TDT4102::Point food;                                         // Random point of food in grid
+        std::default_random_engine foodRandomEngine;        // Machinery to generate random pos for food
+
+        bool gameIsLost = false;                             // Game state
+        
+
+        // --------------- Member functions ------------------------------------------//
+        void drawSnake();      
+        bool isFoodOnSnake();
+        bool hasSnakeCrashed(Direction dir);
+        void sampleFood();                  // Assign position to food member-variable
+        TDT4102::Point nextPoint(Direction dir);     // Find the coords of the next point in given direction of snake
+        bool gameLost(Direction dir);       // Evaluate the state of game (collisions)
+
+    public:
+        /*
+            TO-DO: Complete the declaration and definition of the Game-Window constructor
+        */
+       GameWindow(); 
+       void run();
+};
\ No newline at end of file
diff --git a/templates/_folder_Lectures/O12 - handout Snake/Snake.cpp b/templates/_folder_Lectures/O12 - handout Snake/Snake.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d99721898a55d7ab5c4764b842e0487032df040e
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Snake/Snake.cpp	
@@ -0,0 +1,44 @@
+#include "Snake.h"
+
+Snake::Snake(int gridWidth, int gridHeight, int initSize): snake(){
+    /*
+        Constructor of snake: initialize the snake vector at a random position within the grid
+        Restricted to horisontal alignment only
+    */
+    // Random number machinery
+    std::random_device rd;     // Only used once to initialise (seed) engine
+    std::default_random_engine engine(rd());    // Random-number engine used
+
+    std::uniform_int_distribution<int> uniW(initSize,gridWidth-initSize); // Head of snake  - x-pos 
+    std::uniform_int_distribution<int> uniH(0,gridHeight); // Head of snake - y-pos 
+    TDT4102::Point p = {uniW(engine), uniH(engine)};
+    snake.push_back(p);
+
+    // Add the rest of the body points, linearly behind the head
+    for (int i = 0; i<initSize-1; ++i){
+        snake.push_back(TDT4102::Point{snake.at(i).x-1, snake.at(i).y});
+    }
+
+    
+}
+
+void Snake::updateSnake(TDT4102::Point nextHead, bool didEat){
+    /*
+        Updated the length of the snake, if the food is eaten
+        Translate the whole snake one step further 
+    */
+   
+    if (didEat) {
+        snake.push_back(TDT4102::Point{});      // This point is arbitrary as it will take value of the old "tail" point anyways
+    }
+
+    // Translate the snake one step, begin from the tail 
+    // Assign each block the value of the block in front of it
+    // Except the head, which must be assigned separately to "nexthead" (which is dependent on direction)
+    for (int i = snake.size() - 1; i > 0; --i) {
+        snake[i] = snake[i - 1];  // Shift body points (except head)
+    }
+    
+    snake.at(0) = nextHead;    // Handling head separately
+}
+
diff --git a/templates/_folder_Lectures/O12 - handout Snake/Snake.h b/templates/_folder_Lectures/O12 - handout Snake/Snake.h
new file mode 100644
index 0000000000000000000000000000000000000000..3928e5fbdc107428cbf916ffbed2abefef366261
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Snake/Snake.h	
@@ -0,0 +1,15 @@
+#include <vector>
+#include <random>
+#include "Point.h"
+
+class Snake {
+    private:
+        std::vector<TDT4102::Point> snake;
+    public:
+
+        Snake(int gridWidth, int gridHeight, int initSize);
+
+        void updateSnake(TDT4102::Point nextHead, bool didEat);
+        const std::vector<TDT4102::Point>& getSnake() { return snake; };
+        TDT4102::Point getHead() { return snake[0]; };
+};
\ No newline at end of file
diff --git a/templates/_folder_Lectures/O12 - handout Snake/main.cpp b/templates/_folder_Lectures/O12 - handout Snake/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d489dbc63d96f4f6350fa8db4abe7d6afba07ffa
--- /dev/null
+++ b/templates/_folder_Lectures/O12 - handout Snake/main.cpp	
@@ -0,0 +1,8 @@
+#include "GameWindow.h"
+
+int main() {
+    
+    GameWindow window;
+    window.run();
+    return 0;
+}
\ No newline at end of file