{"id":5960,"date":"2022-10-12T11:51:31","date_gmt":"2022-10-12T10:51:31","guid":{"rendered":"https:\/\/dronesonen.usn.no\/?p=5960"},"modified":"2022-11-29T08:26:10","modified_gmt":"2022-11-29T07:26:10","slug":"connect-4-week-8-10-10-16-10","status":"publish","type":"post","link":"https:\/\/dronesonen.usn.no\/?p=5960","title":{"rendered":"Connect 4 \u2013 Week 8 (10.10 \u2013 16.10)"},"content":{"rendered":"\n<p>This week, we finally added the algorithm to our connect 4 demo python program. You can now choose difficulties from 0 to 5, where 0 equals random turn and 1 to 5 the parameter of the tree depth of the minmax algorithm. We used the implementation from Keith Galli, he made a good YouTube video about it: <a href=\"https:\/\/www.youtube.com\/watch?v=MMLtza3CZFM\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.youtube.com\/watch?v=MMLtza3CZFM<\/a> Just needed to do the adjustment to our working functions and variable names..<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def minimax(board, depth, alpha, beta, maximizing_player):\n    open_columns = get_open_columns(board)\n    is_terminal = winning_move(board, PLAYER_COIN) or winning_move(board, COMPUTER_COIN) or len(\n        get_open_columns(board)) == 0\n    if is_terminal:\n        if winning_move(board, COMPUTER_COIN):\n            return None, 100000000000000\n        elif winning_move(board, PLAYER_COIN):\n            return None, -10000000000000\n        else:  # Game is over, no more valid moves\n            return None, 0\n    if depth == 0:  # Depth is zero\n        return None, score_position(board, COMPUTER_COIN)\n\n    if maximizing_player:\n        value = -math.inf\n        column = random.choice(open_columns)\n        for col in open_columns:\n            b_copy = board.copy()\n            place_coin(b_copy, col, COMPUTER_COIN)\n            new_score = minimax(b_copy, depth - 1, alpha, beta, False)&#091;1]\n            if new_score &gt; value:\n                value = new_score\n                column = col\n            alpha = max(alpha, value)\n            if alpha &gt;= beta:\n                break\n        return column, value<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"445\" height=\"270\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/Screenshot-2022-10-19-213821.jpg\" alt=\"\" class=\"wp-image-6026\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/Screenshot-2022-10-19-213821.jpg 445w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/Screenshot-2022-10-19-213821-300x182.jpg 300w\" sizes=\"auto, (max-width: 445px) 100vw, 445px\" \/><\/figure>\n\n\n\n<p>With difficulty 4 and 5 it&#8217;s impossible to win and even draw is really hard. On difficulty 3 you can play draw really good and winning is quite possible if you are familiar with &#8220;traps&#8221; and looking \/ thinking a bit into the future. Also with more depth, the calculation power needed rises very much! (Every new tree level the possibilities rises exponentially.) Zoran gave as a Rasperry 3 B+ this week and I tried to run the program on it and also on my own Rasperry 3 B+ and my personal computer (with Ryzen 7 processor). Below is a table of how long it takes to calculate one move.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Device and processor<\/strong><\/td><td><strong>Difficulty \/ depth 4<\/strong><\/td><td><strong>Difficulty \/ depth 5<\/strong><\/td><\/tr><tr><td>Laptop with Ryzen 7 processor<\/td><td>&lt; 1 sec<\/td><td>3 sec<\/td><\/tr><tr><td>Rasperry Pi 3 with ARM 4 core processor<\/td><td>4 sec<\/td><td>18 sec<\/td><\/tr><tr><td>Rasperry Pi 1 with Broadcom single core processor<\/td><td>15 sec<\/td><td>1 min 8 sec<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>As you can see, the time improvement from Rasperry Pi 1 to 3 is a quarter! Really good we think..<\/p>\n\n\n\n<p>We also read about buttons via GPIO on rasperry pi. We will have a difficulty button and a start\/stop button. There should be also something like a main menu on the LCD, where you can view the difficulty.. And with the start button you can start out of the main menu. Pressing the button again the game should stop. The problem that came up is that waiting for a button interrupt isn&#8217;t useful, as we cannot play in the meantime.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import RPi.GPIO as GPIO\nBUTTON_GPIO = 18\nif __name__ == '__main__':\n    GPIO.setmode(GPIO.BCM)\n    GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)\n    while True:\n        GPIO.wait_for_edge(BUTTON_GPIO, GPIO.FALLING)\n        print(\"Button pressed.\")<\/code><\/pre>\n\n\n\n<p>So we researched a little bit and found this tutorial: <a rel=\"noreferrer noopener\" href=\"https:\/\/roboticsbackend.com\/raspberry-pi-gpio-interrupts-tutorial\/\" target=\"_blank\">https:\/\/roboticsbackend.com\/raspberry-pi-gpio-interrupts-tutorial\/<\/a><br>There is a function GPIO.add_event_detect() and it will run a callback function as soon as the button is pressed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import signal\nimport sys\nimport RPi.GPIO as GPIO\nBUTTON_GPIO = 16\ndef signal_handler(sig, frame):\n    GPIO.cleanup()\n    sys.exit(0)\ndef button_pressed_callback(channel):\n    print(\"Button pressed!\")\nif __name__ == '__main__':\n    GPIO.setmode(GPIO.BCM)\n    GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)\n    GPIO.add_event_detect(BUTTON_GPIO, GPIO.FALLING, \n            callback=button_pressed_callback, bouncetime=100)\n    \n    signal.signal(signal.SIGINT, signal_handler)\n    signal.pause()<\/code><\/pre>\n\n\n\n<p>So the next idea is to pack the game into a own process or thread, that will be start or stopped by button press. With the use of separate process\/thread, it is also guaranteed that the game is closed properly and a new &#8220;fresh&#8221; game will start after reopen. Also we can easily pass the difficulty into the game. We will have a look into that next week and hope to realize it then already.<br><br><br>We also cutted the whole gameboard. As pictures are saying more than 1000 words, just look into our picture gallery below for our progress and the finished game board \ud83d\ude42<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"770\" height=\"1024\" data-id=\"6034\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110916-770x1024.jpg\" alt=\"\" class=\"wp-image-6034\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110916-770x1024.jpg 770w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110916-226x300.jpg 226w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110916-768x1021.jpg 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110916-1155x1536.jpg 1155w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110916-1540x2048.jpg 1540w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110916-scaled.jpg 1925w\" sizes=\"auto, (max-width: 770px) 100vw, 770px\" \/><figcaption>pushing out the holes<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"770\" data-id=\"6035\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110923-1024x770.jpg\" alt=\"\" class=\"wp-image-6035\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110923-1024x770.jpg 1024w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110923-300x226.jpg 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110923-768x578.jpg 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110923-1536x1155.jpg 1536w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110923-2048x1540.jpg 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>getting the placeholder in position<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"770\" height=\"1024\" data-id=\"6036\" src=\"http:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110930-770x1024.jpg\" alt=\"\" class=\"wp-image-6036\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110930-770x1024.jpg 770w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110930-226x300.jpg 226w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110930-768x1021.jpg 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110930-1155x1536.jpg 1155w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110930-1540x2048.jpg 1540w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012110930-scaled.jpg 1925w\" sizes=\"auto, (max-width: 770px) 100vw, 770px\" \/><figcaption>Fabi thinking about the wood sizes for cutting<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"770\" height=\"1024\" data-id=\"6037\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012125052-770x1024.jpg\" alt=\"\" class=\"wp-image-6037\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012125052-770x1024.jpg 770w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012125052-226x300.jpg 226w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012125052-768x1021.jpg 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012125052-1155x1536.jpg 1155w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012125052-1540x2048.jpg 1540w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012125052-scaled.jpg 1925w\" sizes=\"auto, (max-width: 770px) 100vw, 770px\" \/><figcaption>glue a game stand together<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"770\" height=\"1024\" data-id=\"6038\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133130-770x1024.jpg\" alt=\"\" class=\"wp-image-6038\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133130-770x1024.jpg 770w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133130-226x300.jpg 226w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133130-768x1021.jpg 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133130-1155x1536.jpg 1155w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133130-1540x2048.jpg 1540w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133130-scaled.jpg 1925w\" sizes=\"auto, (max-width: 770px) 100vw, 770px\" \/><figcaption>Rick is happy<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"770\" height=\"1024\" data-id=\"6039\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133142-770x1024.jpg\" alt=\"\" class=\"wp-image-6039\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133142-770x1024.jpg 770w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133142-226x300.jpg 226w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133142-768x1021.jpg 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133142-1155x1536.jpg 1155w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133142-1540x2048.jpg 1540w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133142-scaled.jpg 1925w\" sizes=\"auto, (max-width: 770px) 100vw, 770px\" \/><figcaption>Rick and Jasper improving something in CAD<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"770\" data-id=\"6041\" src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133148-1-1024x770.jpg\" alt=\"\" class=\"wp-image-6041\" srcset=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133148-1-1024x770.jpg 1024w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133148-1-300x226.jpg 300w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133148-1-768x578.jpg 768w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133148-1-1536x1155.jpg 1536w, https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2022\/10\/IMG20221012133148-1-2048x1540.jpg 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>finished gameboard for today! <\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p>The gameboard shown above is almost correct, it just needs a little bit of adjusting the holes to match the LED light on the LED strip. After this part we can lasercut and assemble the top part for dropping the coins in the gameboard. The difficulty is going to be that the coins only have a small margin to the front and the back so we have to make sure that the coindropper is pretty precize. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>This week, we finally added the algorithm to our connect 4 demo python program. You can now choose difficulties from 0 to 5, where 0 equals random turn and 1 to 5 the parameter of the tree depth of the minmax algorithm. We used the implementation from Keith Galli, he made a good YouTube video [&hellip;]<\/p>\n","protected":false},"author":90,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[98,93,1],"tags":[85],"class_list":["post-5960","post","type-post","status-publish","format-standard","hentry","category-connect-4","category-smart-systems-2022","category-uncategorized","tag-connect-4"],"_links":{"self":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/5960","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/users\/90"}],"replies":[{"embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5960"}],"version-history":[{"count":26,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/5960\/revisions"}],"predecessor-version":[{"id":6071,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/5960\/revisions\/6071"}],"wp:attachment":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5960"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5960"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5960"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}