{"id":259,"date":"2023-01-11T17:33:45","date_gmt":"2023-01-11T17:33:45","guid":{"rendered":"https:\/\/trewest.dev\/blog\/?p=259"},"modified":"2023-12-05T09:34:34","modified_gmt":"2023-12-05T09:34:34","slug":"project-mini-stacker","status":"publish","type":"post","link":"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/11\/project-mini-stacker\/","title":{"rendered":"Project: Mini Stacker"},"content":{"rendered":"<div class=\"wp-post-series-box series-project-overviews wp-post-series-box--expandable\">\n\t\t\t<input id=\"collapsible-series-project-overviews69e8ce595636c\" class=\"wp-post-series-box__toggle_checkbox\" type=\"checkbox\">\n\t\n\t<label\n\t\tclass=\"wp-post-series-box__label\"\n\t\t\t\t\tfor=\"collapsible-series-project-overviews69e8ce595636c\"\n\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\t\t<p class=\"wp-post-series-box__name wp-post-series-name\">\n\t\t\tThis is post 6 of 21 in the series <em>&ldquo;Project Overviews&rdquo;<\/em>\t\t<\/p>\n\t\t\t\t\t<div class=\"wp-post-series-box__description wp-post-series-description\">\n\t\t\t\t<p>A series of posts detailing and highlighting projects that I&#8217;ve made.<\/p>\n\t\t\t<\/div>\n\t\t\t<\/label>\n\n\t\t\t<div class=\"wp-post-series-box__posts\">\n\t\t\t<ol>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/10\/project-bugtrakt\/\">Project: Bugtrakt<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/10\/project-imgalib\/\">Project: Imgalib<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/10\/project-go-fish\/\">Project: Go Fish!<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/11\/project-trewest-dev\/\">Project: trewest.dev<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/11\/arduino-light-effects\/\">Arduino Light effects<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><span class=\"wp-post-series-box__current\">Project: Mini Stacker<\/span><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/12\/project-arduino-nes-controller\/\">Project: Arduino NES Controller<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/12\/project-metroidvania-like\/\">Project: Metroidvania-Like<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/12\/project-susminer\/\">Project: Susminer<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/12\/project-farming-demo\/\">Project: Farming Demo<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/13\/project-vrc-basement\/\">Project: VRC Basement<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/13\/project-hash-clear\/\">Project: Hash Clear<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/13\/project-titan-help\/\">Project: Titan Help<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/13\/project-computer-craft-scripts\/\">Project: Computer Craft Scripts<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/15\/project-esp8266-plant-watering\/\">Project: ESP8266 Plant Watering<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/15\/project-golf-demo\/\">Project: Golf Demo<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/01\/15\/project-ghost-holic\/\">Project: Ghost Holic<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2023\/03\/27\/project-multi-chat-viewer\/\">Project: Multi-Chat Viewer<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2024\/08\/22\/project-interview-simulator\/\">Project: Interview Simulator<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2024\/10\/18\/project-healers-journey\/\">Project: Healer&#8217;s Journey<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/trewest.dev\/blog\/index.php\/2024\/10\/18\/project-biota\/\">Project: Biota<\/a><\/li>\n\t\t\t\t\t\t\t<\/ol>\n\t\t<\/div>\n\t<\/div>\n\n<p>Status: <span style=\"color:green\">Complete<\/span><br>Type: Microcontroller<br>Technology: Arduino UNO, C++<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/wokwi.com\/projects\/313674725926634049\" target=\"_blank\" rel=\"noreferrer noopener\">Play Now<\/a><\/div>\n\n\n\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/trewest.dev\">Return to Portfolio<\/a><\/div>\n<\/div>\n\n\n\n<p>Mini Stacker was a bit of a challenge I undertook to remake a favorite arcade game of mine as a project.  This was one of my introductory projects into the world of Arduino and as such wasn&#8217;t be best planned out.  It works simply with an array of light strips to form an image of the game.  I also included a beeping speaker for the sake of having a little audio.  The game itself is simple, you press a button to place a block, and if the block is not on another block it falls.  If you lose all the blocks you lose the game.   Since I originally made this in a Arduino simulator\/emulator, you can play it now using the button above.  Originally I was going to make this in real life but sadly soldering a lot of light strips together and in the right order is a much harder thing to pull off than I originally thought (Turns out pulling off the small soldering pads is very easy!) so I put that on hiatus until I rework the code a bit to render onto a large LED array that I can simply plug into a board instead of a bunch of light strips.  Anyhow, code and screenshots of the emulator are below.  <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"475\" height=\"657\" src=\"https:\/\/trewest.dev\/blog\/wp-content\/uploads\/2023\/01\/image-22.png\" alt=\"\" class=\"wp-image-260\" srcset=\"https:\/\/trewest.dev\/blog\/wp-content\/uploads\/2023\/01\/image-22.png 475w, https:\/\/trewest.dev\/blog\/wp-content\/uploads\/2023\/01\/image-22-217x300.png 217w\" sizes=\"auto, (max-width: 475px) 100vw, 475px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"476\" height=\"637\" src=\"https:\/\/trewest.dev\/blog\/wp-content\/uploads\/2023\/01\/image-23.png\" alt=\"\" class=\"wp-image-261\" srcset=\"https:\/\/trewest.dev\/blog\/wp-content\/uploads\/2023\/01\/image-23.png 476w, https:\/\/trewest.dev\/blog\/wp-content\/uploads\/2023\/01\/image-23-224x300.png 224w\" sizes=\"auto, (max-width: 476px) 100vw, 476px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/Mini Stacker is an attempt at cloning the Arcade game Stacker by LAI Games.\n\/\/Using LED Strips, a button, and optionally a Buzzer.\n\/\/Oh, and of course the Arduino Uno\n\/\/Animations and sounds aren't accurate to the machine\/machines.\n\/\/Also my first time coding for Arduino.\n#include &lt;FastLED.h&gt;\n\n#define NUM_STRIPS 7\n#define NUM_LEDS_PER_STRIP 12\n#define BUTTON_PIN 4\nCRGB leds&#91;NUM_STRIPS]&#91;NUM_LEDS_PER_STRIP];\n\nbool clicked = false;\n\nbool goingLeft = true; \/\/ Going left if true, right if false.\n\nconst int buzzerPin = 6; \/\/Is there a buzzer, set to -1 to disable.\nconst int top = NUM_LEDS_PER_STRIP; \/\/ Basically the height of the strips, this is adjustable if you have a larger matrix\nconst int bottom = top-1; \/\/ Subtract one from the top if using the whole strip.\nconst int maxHeight = bottom - top;\n\nCRGB blockColor = CRGB::Blue;\n\nunsigned long prevMillis = 0; \/\/ The previous time in milliseconds\nunsigned long curMillis = 0; \/\/Current time in milliseconds, to prevent multiple calls to millis()\nunsigned long buttonwait =0;\nconst long animationDuration = 2000; \/\/ Animation for loss of block\nconst long defaultInterval = 200; \/\/ The starting time between updates\nconst int intervalModifier = 15; \/\/ How much the interval should change for every success.\n\/\/Your maximum interval modifier should equal defaultInterval \/ top\nlong maxSpeed = 10; \/\/ Maximum allowed speed for the blocks.  Never set to negative\nlong interval = defaultInterval; \/\/ Time between updates.  This shouldn't ever be made a const, as it will change.\n\nint cursize = 3; \/\/Size of the stacking block\nint curpos = 2; \/\/ Position of the block\nint currow = bottom;\/\/What row of LEDS the block is in\n\n\/\/ For mirroring strips, all the \"special\" stuff happens just in setup.  We\n\/\/ just addLeds multiple times, once for each strip\nvoid setup() {\n\n  Serial.begin(115200);\n\n  \/\/Initializing the FastLED\/Neopixel Array\n  FastLED.addLeds&lt;NEOPIXEL, 10&gt;(leds&#91;0], NUM_LEDS_PER_STRIP);\n  FastLED.addLeds&lt;NEOPIXEL, 11&gt;(leds&#91;1], NUM_LEDS_PER_STRIP);\n  FastLED.addLeds&lt;NEOPIXEL, 12&gt;(leds&#91;2], NUM_LEDS_PER_STRIP);\n  FastLED.addLeds&lt;NEOPIXEL, 13&gt;(leds&#91;3], NUM_LEDS_PER_STRIP);\n  FastLED.addLeds&lt;NEOPIXEL, 9&gt;(leds&#91;4], NUM_LEDS_PER_STRIP);\n  FastLED.addLeds&lt;NEOPIXEL, 8&gt;(leds&#91;5], NUM_LEDS_PER_STRIP);\n  FastLED.addLeds&lt;NEOPIXEL, 7&gt;(leds&#91;6], NUM_LEDS_PER_STRIP);\n\n\n  if (maxSpeed&lt;0) {\n    maxSpeed = 0;\n    Serial.println(\"Error: Max speed was set to negative.\");\n    }\n\n  pinMode(BUTTON_PIN, INPUT_PULLUP);\n  int value = digitalRead((BUTTON_PIN));\n}\nint lastState = HIGH;\nint value = HIGH;\n\nbool checkAir (); \/\/ Checking if blocks are on air or blocks\nvoid drawBlock(); \/\/ Drawing call \nvoid onUpdate(); \/\/ Update call\nvoid resetGame(); \/\/ Function to reset the game\nvoid failState(int echo); \/\/ Called when the player loses\nvoid winState(); \/\/ Called when the player wins\nvoid animatedrop(int pos, int width); \/\/Drop animation\nvoid animatedrop(int pos, int width, bool isFail); \/\/Drop animation if the player loses\nvoid buttonPressed(); \/\/Called on button press.\n\n\n  void onUpdate()\n  {\n    if (goingLeft) {              \/\/ If we're moving left\n    if (curpos &gt; 0) {           \/\/ Check if we can go left\n        curpos--;               \/\/ If we can, let's go left\n      } else {                  \/\/Otherwise...\n        curpos++;               \/\/We'll go right\n        goingLeft =false;       \/\/And make sure we're really going right.\n      }\n    } else {                    \/\/If we're going right\n      if (curpos+cursize &lt; 7) { \/\/Check if we can go right\n        curpos++;               \/\/If we can, let's go right.\n      } else {                  \/\/Otherwise...\n        curpos--;               \/\/Go left\n        goingLeft=true;         \/\/And really go left\n      }\n    }\n    drawBlock(); \/\/ Finally we may draw\n    prevMillis = curMillis;\n  }\n\n  void drawBlock() \n  {\n    leds&#91;curpos]&#91;currow] = blockColor; \/\/ We always draw the leftmost block\n    if (cursize&gt;1) \/\/Then check if there's more\n    {\n      if (cursize==3) \/\/If there's three we can draw the third\n      {\n        leds&#91;curpos+2]&#91;currow] = blockColor; \/\/Drawing the third\n      }\n      leds&#91;curpos+1]&#91;currow] = blockColor; \/\/If we're more than one, it should be at least two.  So draw the second.\n    }\n\n    if (goingLeft) \/\/If the movement is going left\n    {\n      leds&#91;curpos+cursize]&#91;currow] = CRGB::Black; \/\/ Clear the previous rightmost\n    }\n    else \n    {\n      leds&#91;curpos-1]&#91;currow] = CRGB::Black; \/\/Otherwise we're going right, and only have to remove one to the left\n    }\n\n    FastLED.show(); \/\/ Then we can draw\n\n    \/\/Serial.print(\"X: \"); Serial.print(curpos); Serial.print(\" Y: \"); Serial.print(currow);Serial.print(\"\\n\");\n  }\n\n  bool checkAir () \n  {\n    Serial.println(\"Checking Air\");\n    if (leds&#91;curpos]&#91;currow+1] == CRGB(0,0,0)) { \/\/ If the leftmost block has fallen\n      if (cursize&gt;1) { \/\/ If there's more than one block\n        if (cursize==3) \/\/ if 3 wide\n        {\n          if (leds&#91;curpos+2]&#91;currow+1] == CRGB(0,0,0)) { \/\/ If the bar isnt seated\n            \/\/Failstate, the triple block has fallen\n            failState(1);\n            return true;\n          }\n          else if (leds&#91;curpos+1]&#91;currow+1] == CRGB(0,0,0)) { \/\/If this is call\n            cursize -= 2; \/\/2 blocks have dropped \n            animatedrop(curpos,2);\n          }\n          else {\n            cursize--; \/\/ 1 block has dropped \n            animatedrop(curpos,1);\n          }\n        }\n        else if (leds&#91;curpos+1]&#91;currow+1] == CRGB(0,0,0)) { \/\/ If its greater than one but less than three it's two wide\n          \/\/Failstate, the double block has fallen\n           failState(2);\n           return true;\n        }\n        else {\n          cursize--; \/\/ one block has dropped\n          animatedrop(curpos,1);\n        }\n      }\n      else { \/\/ If there's only one block\n        \/\/Failstate, the single block has fallen\n         failState(3);\n         return true;\n      }\n    }\n    else \/\/ If the leftmost block hasn't fallen \n    {\n      \/\/Serial.println(\"Left didnt fall\");\n      if (cursize&gt;1) { \/\/ If there's more than one block\n        if (cursize==3) \/\/ if 3 wide\n        {\n          if (leds&#91;curpos+1]&#91;currow+1] == CRGB(0,0,0)) { \/\/ If the second isn't seated\n            cursize -= 2; \/\/2 blocks have dropped \n            animatedrop(curpos+1,2);\n          }\n          else if (leds&#91;curpos+2]&#91;currow+1] == CRGB(0,0,0)) { \/\/if the third isn't seated\n            cursize -= 1; \/\/1 blocks have dropped \n            animatedrop(curpos+2,1);\n          }\n          else  \/\/ Nothing fallen scenario\n          {\n            if (buzzerPin != -1) \n            {\n              tone(buzzerPin, 1000, 100);\n            }\n          }\n        }\n        else if (leds&#91;curpos+1]&#91;currow+1] == CRGB(0,0,0)) {\/\/ if there's two blocks, check only the rightmost\n          cursize -= 1; \/\/1 blocks have dropped \n          animatedrop(curpos+1,1);\n        }\n        else \/\/Nothing fallen, with only two blocks \n        {\n          if (buzzerPin != -1)  \/\/If we can buzz\n          {\n            tone(buzzerPin, 1000, 100);\/\/Buzz\n          }\n        }\n      }\n      else { \/\/ If there's only one block\n         \/\/failState(4);\n         \/\/Congrats!  Nothing happens!\n            if (buzzerPin != -1) \n            {\n              tone(buzzerPin, 1000, 100);\n            }\n      }\n    }\n    return false;\n  }\n\n  void resetGame() \n  {\n    \/\/Begin resetting the scenario\n    curpos=2;\n    currow = bottom;\n    cursize=3;\n    interval = defaultInterval;\n\n    \/\/ This outer loop will go over each strip, one at a time\n    for(int x = 0; x &lt; NUM_STRIPS; x++) {\n    \/\/ This inner loop will go over each led in the current strip, one at a time\n      for(int i = 0; i &lt; NUM_LEDS_PER_STRIP; i++) {\n        leds&#91;x]&#91;i] = CRGB::Black;\n      }\n    }\n    FastLED.show();\n\n    curMillis = millis();\n    prevMillis = curMillis; \/\/ The previous time in milliseconds\n  }\n  void winState() \n  {\n    Serial.println(\"Winstate!\");\/\/Output success\n    if (buzzerPin != -1) \/\/play a little song if we can\n    {\n      tone(buzzerPin, 1000, 100);\n      delay(100);\n      tone(buzzerPin, 1200, 100);\n      delay(100);\n      tone(buzzerPin, 1000, 100);\n    }\n\n    resetGame(); \/\/ Reset the game to play again\n  }\n\n  void failState(int echo) \/\/Function for the ending of the game\n  {\n    \/*Serial.print(\"\\nFailstate! \");\n    Serial.print(echo);\n    Serial.print(\"\\n\");*\/\n    \/\/Animate the failure\n    animatedrop(curpos,cursize,true);\n    resetGame(); \/\/Reset the game to play again\n  }\n\n    void animatedrop(int pos, int width) \/\/This is the function that animates the loss of blocks when the player overshoots\n    {\n      \/\/Serial.println(\"Animating\");\n      unsigned long tillAnimation = curMillis + animationDuration;\n      unsigned long blinkTimer = curMillis + (animationDuration\/8);\n      bool blink = false;\n      while(tillAnimation &gt; curMillis) \n      {\n        curMillis = millis();\n        prevMillis = curMillis;\n\n        if (blinkTimer &lt; curMillis) \n        {\n          if (blink) \/\/if off\n          {\n            for (int i = 0; i&lt;width; i++) \n            {\n              leds&#91;pos+i]&#91;currow] = blockColor;\n              \n            }\n            FastLED.show();\n            blink = false;\n            blinkTimer = curMillis + (animationDuration\/8);\n            \/\/Serial.println(\"Blinking on\");\n\n            if (buzzerPin != -1) \n            {\n              tone(buzzerPin, 262, (animationDuration\/8));\n            }\n          }\n          else \n          {\n            for (int i = 0; i&lt;width; i++) \n            {\n              leds&#91;pos+i]&#91;currow] = CRGB::Black;\n              \n            }\n            FastLED.show();\n            \/\/Serial.println(\"Blinking off\");\n            if (buzzerPin != -1) \n            {\n              tone(buzzerPin, 288, (animationDuration\/8));\n            }\n            blink = true;\n            blinkTimer = curMillis + (animationDuration\/8);\n          }\n          FastLED.show();\n        }\n      }\n    }\n\n    void animatedrop(int pos, int width, bool isFail) \/\/ This one is only called if it's a fail\n    { \/\/ This is done to make a different noise, can definitely be written more compactly, but I'm coding this lazily\n      \/\/Serial.println(\"Animating\");\n      unsigned long tillAnimation = curMillis + animationDuration;\n      unsigned long blinkTimer = curMillis + (animationDuration\/8);\n      unsigned int buzz = 600;\n      unsigned int buzzI = 10;\n      bool blink = false;\n      while(tillAnimation &gt; curMillis) \n      {\n        curMillis = millis();\n        prevMillis = curMillis;\n\n        if (blinkTimer &lt; curMillis) \n        {\n          if (blink) \/\/if off\n          {\n            for (int i = 0; i&lt;width; i++) \n            {\n              leds&#91;pos+i]&#91;currow] = blockColor;\n              \n            }\n            FastLED.show();\n            blink = false;\n            blinkTimer = curMillis + (animationDuration\/8);\n            \/\/Serial.println(\"Blinking on\");\n          }\n          else \n          {\n            for (int i = 0; i&lt;width; i++) \n            {\n              leds&#91;pos+i]&#91;currow] = CRGB::Black;\n              \n            }\n            FastLED.show();\n            \/\/Serial.println(\"Blinking off\");\n            blink = true;\n            blinkTimer = curMillis + (animationDuration\/8);\n          }\n          if (buzzerPin != -1) \n          {\n            tone(buzzerPin, buzz, (animationDuration\/8));\n          }\n          buzz -= buzzI;\n          FastLED.show();\n        }\n      }\n    }\n\n  void buttonPressed() \n  {\n    if (value== HIGH) \n    {\n      \/\/Serial.println(\"Button Released\");\n      clicked = true;\n      buttonwait = curMillis;\n    }\n    else if (value == LOW)\n    {\n      \/\/Serial.println(\"Button Pressed\");\n      if (!clicked) \n      {\n      if (currow != bottom) \n      {\n        if (checkAir()) \n        {\n          return 0;\n        }\n      }\n      else \/\/ Using an else statement here to play the sound that check air would play normally on success \n      {\n        if (buzzerPin != -1) \n          {\n            tone(buzzerPin, 1000, 100);\n          }\n      }\n      currow--; \/\/ Going upwards on the rows\n      if (currow &lt;= maxHeight ) \n      {\n        winState();\n        return 0;\n      }\n      if (currow &lt; (bottom - (top \/ 4) ) &amp;&amp; cursize == 3) \n      {\n        cursize--;\n      }\n      else if (currow &lt; (bottom - (top \/ 2) ) &amp;&amp; cursize == 2) \n      {\n        cursize--;\n      }\n      onUpdate();\n      interval -= intervalModifier;\n      if (interval &lt; maxSpeed) \/\/ prevention from going over the max speed\n      {\n        interval = maxSpeed;\n      }\n      clicked = true;\n      buttonwait = curMillis;\n      }\n      \n    }\n    \n  }\n\n\n\nvoid loop() {\n  curMillis = millis();\n  value = digitalRead((BUTTON_PIN));\n  if (value != lastState) {\n      lastState = value;\n      buttonPressed();\n    }\n    \n    if (curMillis - prevMillis &gt;= interval) \/\/If the interval between updates has been reached\n    {\n      onUpdate(); \/\/ update\n    }\n\n    if (clicked) \n    {\n      if (curMillis - buttonwait &gt;= 50) \n      {\n        clicked = false;\n      }\n    }\n  \n    \/\/delay(500); DELAY IS NASTY.  DO NOT USE DELAY\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Mini Stacker was a bit of a challenge I undertook to remake a favorite arcade game of mine as a project. This was one of my introductory projects into the world of Arduino and as such wasn\u2019t be best planned out. It works simply with an&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48,45,4,8],"tags":[26,16],"post_series":[53],"class_list":["post-259","post","type-post","status-publish","format-standard","hentry","category-arduino","category-c-coding","category-coding","category-project","tag-arduino","tag-c","post_series-project-overviews"],"_links":{"self":[{"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/posts\/259","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=259"}],"version-history":[{"count":3,"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/posts\/259\/revisions"}],"predecessor-version":[{"id":353,"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/posts\/259\/revisions\/353"}],"wp:attachment":[{"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=259"},{"taxonomy":"post_series","embeddable":true,"href":"https:\/\/trewest.dev\/blog\/index.php\/wp-json\/wp\/v2\/post_series?post=259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}