2048 Webgame bot











up vote
0
down vote

favorite
1












So there is this game 2048. You can play it here



I wrote a python script which "plays" the game on the website by clicking the arrow keys.



I would like to know what can be improved.
Is it a good idea to check the Try again button with exceptions? Is there a better way?



Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?



play_2048.py



"""
Opens the webpage of the 2048 game and plays it repeadly.
Needs chromedriver in the directory of the script. Download it here:
https://sites.google.com/a/chromium.org/chromedriver/downloads
"""

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

def play_2048():
"""
Main lopp of script. First opens the browser to the game page.
Then pushes the arrow keys to play the game.
If a game over occurs the try again button on the page is klicked
to repeat the game
"""
browser = webdriver.Chrome()
browser.get('https://play2048.co/')

html = browser.find_element_by_tag_name('html')

while True:
html.send_keys(Keys.RIGHT)
html.send_keys(Keys.UP)
html.send_keys(Keys.LEFT)
html.send_keys(Keys.DOWN)

try:
retry = browser.find_element_by_link_text('Try again')
except:
continue
else:
retry.click()

if __name__ == '__main__':
play_2048()









share|improve this question




























    up vote
    0
    down vote

    favorite
    1












    So there is this game 2048. You can play it here



    I wrote a python script which "plays" the game on the website by clicking the arrow keys.



    I would like to know what can be improved.
    Is it a good idea to check the Try again button with exceptions? Is there a better way?



    Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?



    play_2048.py



    """
    Opens the webpage of the 2048 game and plays it repeadly.
    Needs chromedriver in the directory of the script. Download it here:
    https://sites.google.com/a/chromium.org/chromedriver/downloads
    """

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys

    def play_2048():
    """
    Main lopp of script. First opens the browser to the game page.
    Then pushes the arrow keys to play the game.
    If a game over occurs the try again button on the page is klicked
    to repeat the game
    """
    browser = webdriver.Chrome()
    browser.get('https://play2048.co/')

    html = browser.find_element_by_tag_name('html')

    while True:
    html.send_keys(Keys.RIGHT)
    html.send_keys(Keys.UP)
    html.send_keys(Keys.LEFT)
    html.send_keys(Keys.DOWN)

    try:
    retry = browser.find_element_by_link_text('Try again')
    except:
    continue
    else:
    retry.click()

    if __name__ == '__main__':
    play_2048()









    share|improve this question


























      up vote
      0
      down vote

      favorite
      1









      up vote
      0
      down vote

      favorite
      1






      1





      So there is this game 2048. You can play it here



      I wrote a python script which "plays" the game on the website by clicking the arrow keys.



      I would like to know what can be improved.
      Is it a good idea to check the Try again button with exceptions? Is there a better way?



      Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?



      play_2048.py



      """
      Opens the webpage of the 2048 game and plays it repeadly.
      Needs chromedriver in the directory of the script. Download it here:
      https://sites.google.com/a/chromium.org/chromedriver/downloads
      """

      from selenium import webdriver
      from selenium.webdriver.common.keys import Keys

      def play_2048():
      """
      Main lopp of script. First opens the browser to the game page.
      Then pushes the arrow keys to play the game.
      If a game over occurs the try again button on the page is klicked
      to repeat the game
      """
      browser = webdriver.Chrome()
      browser.get('https://play2048.co/')

      html = browser.find_element_by_tag_name('html')

      while True:
      html.send_keys(Keys.RIGHT)
      html.send_keys(Keys.UP)
      html.send_keys(Keys.LEFT)
      html.send_keys(Keys.DOWN)

      try:
      retry = browser.find_element_by_link_text('Try again')
      except:
      continue
      else:
      retry.click()

      if __name__ == '__main__':
      play_2048()









      share|improve this question















      So there is this game 2048. You can play it here



      I wrote a python script which "plays" the game on the website by clicking the arrow keys.



      I would like to know what can be improved.
      Is it a good idea to check the Try again button with exceptions? Is there a better way?



      Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?



      play_2048.py



      """
      Opens the webpage of the 2048 game and plays it repeadly.
      Needs chromedriver in the directory of the script. Download it here:
      https://sites.google.com/a/chromium.org/chromedriver/downloads
      """

      from selenium import webdriver
      from selenium.webdriver.common.keys import Keys

      def play_2048():
      """
      Main lopp of script. First opens the browser to the game page.
      Then pushes the arrow keys to play the game.
      If a game over occurs the try again button on the page is klicked
      to repeat the game
      """
      browser = webdriver.Chrome()
      browser.get('https://play2048.co/')

      html = browser.find_element_by_tag_name('html')

      while True:
      html.send_keys(Keys.RIGHT)
      html.send_keys(Keys.UP)
      html.send_keys(Keys.LEFT)
      html.send_keys(Keys.DOWN)

      try:
      retry = browser.find_element_by_link_text('Try again')
      except:
      continue
      else:
      retry.click()

      if __name__ == '__main__':
      play_2048()






      python beginner selenium 2048






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 10 at 19:58









      200_success

      128k15149412




      128k15149412










      asked Dec 10 at 19:16









      Sandro4912

      801121




      801121






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          There isn't really much here to comment on, since there isn't even AI involved.



          The only thing that stands out to me is your use of a silent "catch-all" try block:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except: # Big problem here
          continue

          else:
          retry.click()


          You're catching every exception, and simply ignoring them. In this particular case the ramifications aren't huge. Say in the future though you add a second function to do some processing and decide to put it in the try (for whatever reason). Something like:



          try:
          retry = browser.find_element_by_link_text('Try again')
          do_something_with_retry(retry) # This throws. Would you ever know that though?

          except:
          continue

          else:
          retry.click()


          And lets say that do_something_with_retry is improperly tested, or some unforeseen circumstance comes up, and suddenly do_something_with_retry starts throwing exceptions. Would you ever even know that there was an exception thrown? How would you debug your code failing in that case? It would be much better to be specific about what you need to catch, and deal with that only. As you can see in the API
          documentation, find_element_by_link_text is documented to throw a NoSuchElementException if something fails. Catch that instead, so irrelevant errors aren't silently ignored as well:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except NoSuchElementException as e: # Be specific!
          continue

          else:
          retry.click()


          Now anything other than a NoSuchElementException will cause your program to crash. This is a good thing though. You don't want fundamentally broken code to run.



          Don't make your code vulnerable to silly mistakes that may happen in the future. Silly mistakes happen (like improperly tested functions). It's best that they fail catastrophically so they can be detected and fixed.



          Of course though, the better option to handling the addition of do_something_with_retry would be, if possible, to just not group it in the try in the first place. Again though, mistakes happen.





          As for




          Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?




          That involves writing up an AI to play the game, and is no small feat. That would be beyond the scope of a Code Review unfortunately.






          share|improve this answer























          • if i define name 'NoSuchElementException' is not defined it is not defined
            – Sandro4912
            Dec 11 at 16:50










          • @Sandro4912 You need to import it from selenium. That's not a standard exception.
            – Carcigenicate
            Dec 11 at 16:52










          • it worked by adding from selenium.common.exceptions import NoSuchElementException
            – Sandro4912
            Dec 11 at 16:54




















          up vote
          1
          down vote













          A first step towards writing an AI is to give this an interface.



          First, let's rewrite the "AI" you are currently using as a class:



          from itertools import cycle

          class Cycler:
          def __init__(self):
          self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])

          def next(self, *args):
          return next(self.cycle)


          Which you can use like this in your current code:



          ai = Cycler()
          while True:
          html.send_keys(ai.next())
          try:
          ...


          In the future you might want to be smarter than that and for that you would need the state of the board to be passed along to the AI.



          Class GameStatePrinter(Cycler):
          def next(self, game_state, *args):
          print(game_state)
          return super(self, GameStatePrinter).next(*args)


          This is not really any smarter, but you can pass it the current game state and it will print it:



          ai = GameStatePrinter()
          while True:
          current_state = get_current_state(html)
          html.send_keys(ai.next(current_state))
          ...


          An actual smart bot would then of course act differently according to the information in the board, whereas this one just does the same thing as Cycler, which it inherits from.



          This logic is left as an exercise for the reader.






          share|improve this answer





















          • i tryed adding the first part but in the line self.cycle = cycle[Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN] it throws 'type' object is not subscriptable so maybe the keys don't work with cycler
            – Sandro4912
            Dec 11 at 17:05










          • @Sandro4912: You missed the parenthesis around the list, it should be self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])
            – Graipher
            Dec 11 at 17:07











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209386%2f2048-webgame-bot%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          4
          down vote



          accepted










          There isn't really much here to comment on, since there isn't even AI involved.



          The only thing that stands out to me is your use of a silent "catch-all" try block:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except: # Big problem here
          continue

          else:
          retry.click()


          You're catching every exception, and simply ignoring them. In this particular case the ramifications aren't huge. Say in the future though you add a second function to do some processing and decide to put it in the try (for whatever reason). Something like:



          try:
          retry = browser.find_element_by_link_text('Try again')
          do_something_with_retry(retry) # This throws. Would you ever know that though?

          except:
          continue

          else:
          retry.click()


          And lets say that do_something_with_retry is improperly tested, or some unforeseen circumstance comes up, and suddenly do_something_with_retry starts throwing exceptions. Would you ever even know that there was an exception thrown? How would you debug your code failing in that case? It would be much better to be specific about what you need to catch, and deal with that only. As you can see in the API
          documentation, find_element_by_link_text is documented to throw a NoSuchElementException if something fails. Catch that instead, so irrelevant errors aren't silently ignored as well:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except NoSuchElementException as e: # Be specific!
          continue

          else:
          retry.click()


          Now anything other than a NoSuchElementException will cause your program to crash. This is a good thing though. You don't want fundamentally broken code to run.



          Don't make your code vulnerable to silly mistakes that may happen in the future. Silly mistakes happen (like improperly tested functions). It's best that they fail catastrophically so they can be detected and fixed.



          Of course though, the better option to handling the addition of do_something_with_retry would be, if possible, to just not group it in the try in the first place. Again though, mistakes happen.





          As for




          Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?




          That involves writing up an AI to play the game, and is no small feat. That would be beyond the scope of a Code Review unfortunately.






          share|improve this answer























          • if i define name 'NoSuchElementException' is not defined it is not defined
            – Sandro4912
            Dec 11 at 16:50










          • @Sandro4912 You need to import it from selenium. That's not a standard exception.
            – Carcigenicate
            Dec 11 at 16:52










          • it worked by adding from selenium.common.exceptions import NoSuchElementException
            – Sandro4912
            Dec 11 at 16:54

















          up vote
          4
          down vote



          accepted










          There isn't really much here to comment on, since there isn't even AI involved.



          The only thing that stands out to me is your use of a silent "catch-all" try block:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except: # Big problem here
          continue

          else:
          retry.click()


          You're catching every exception, and simply ignoring them. In this particular case the ramifications aren't huge. Say in the future though you add a second function to do some processing and decide to put it in the try (for whatever reason). Something like:



          try:
          retry = browser.find_element_by_link_text('Try again')
          do_something_with_retry(retry) # This throws. Would you ever know that though?

          except:
          continue

          else:
          retry.click()


          And lets say that do_something_with_retry is improperly tested, or some unforeseen circumstance comes up, and suddenly do_something_with_retry starts throwing exceptions. Would you ever even know that there was an exception thrown? How would you debug your code failing in that case? It would be much better to be specific about what you need to catch, and deal with that only. As you can see in the API
          documentation, find_element_by_link_text is documented to throw a NoSuchElementException if something fails. Catch that instead, so irrelevant errors aren't silently ignored as well:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except NoSuchElementException as e: # Be specific!
          continue

          else:
          retry.click()


          Now anything other than a NoSuchElementException will cause your program to crash. This is a good thing though. You don't want fundamentally broken code to run.



          Don't make your code vulnerable to silly mistakes that may happen in the future. Silly mistakes happen (like improperly tested functions). It's best that they fail catastrophically so they can be detected and fixed.



          Of course though, the better option to handling the addition of do_something_with_retry would be, if possible, to just not group it in the try in the first place. Again though, mistakes happen.





          As for




          Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?




          That involves writing up an AI to play the game, and is no small feat. That would be beyond the scope of a Code Review unfortunately.






          share|improve this answer























          • if i define name 'NoSuchElementException' is not defined it is not defined
            – Sandro4912
            Dec 11 at 16:50










          • @Sandro4912 You need to import it from selenium. That's not a standard exception.
            – Carcigenicate
            Dec 11 at 16:52










          • it worked by adding from selenium.common.exceptions import NoSuchElementException
            – Sandro4912
            Dec 11 at 16:54















          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          There isn't really much here to comment on, since there isn't even AI involved.



          The only thing that stands out to me is your use of a silent "catch-all" try block:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except: # Big problem here
          continue

          else:
          retry.click()


          You're catching every exception, and simply ignoring them. In this particular case the ramifications aren't huge. Say in the future though you add a second function to do some processing and decide to put it in the try (for whatever reason). Something like:



          try:
          retry = browser.find_element_by_link_text('Try again')
          do_something_with_retry(retry) # This throws. Would you ever know that though?

          except:
          continue

          else:
          retry.click()


          And lets say that do_something_with_retry is improperly tested, or some unforeseen circumstance comes up, and suddenly do_something_with_retry starts throwing exceptions. Would you ever even know that there was an exception thrown? How would you debug your code failing in that case? It would be much better to be specific about what you need to catch, and deal with that only. As you can see in the API
          documentation, find_element_by_link_text is documented to throw a NoSuchElementException if something fails. Catch that instead, so irrelevant errors aren't silently ignored as well:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except NoSuchElementException as e: # Be specific!
          continue

          else:
          retry.click()


          Now anything other than a NoSuchElementException will cause your program to crash. This is a good thing though. You don't want fundamentally broken code to run.



          Don't make your code vulnerable to silly mistakes that may happen in the future. Silly mistakes happen (like improperly tested functions). It's best that they fail catastrophically so they can be detected and fixed.



          Of course though, the better option to handling the addition of do_something_with_retry would be, if possible, to just not group it in the try in the first place. Again though, mistakes happen.





          As for




          Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?




          That involves writing up an AI to play the game, and is no small feat. That would be beyond the scope of a Code Review unfortunately.






          share|improve this answer














          There isn't really much here to comment on, since there isn't even AI involved.



          The only thing that stands out to me is your use of a silent "catch-all" try block:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except: # Big problem here
          continue

          else:
          retry.click()


          You're catching every exception, and simply ignoring them. In this particular case the ramifications aren't huge. Say in the future though you add a second function to do some processing and decide to put it in the try (for whatever reason). Something like:



          try:
          retry = browser.find_element_by_link_text('Try again')
          do_something_with_retry(retry) # This throws. Would you ever know that though?

          except:
          continue

          else:
          retry.click()


          And lets say that do_something_with_retry is improperly tested, or some unforeseen circumstance comes up, and suddenly do_something_with_retry starts throwing exceptions. Would you ever even know that there was an exception thrown? How would you debug your code failing in that case? It would be much better to be specific about what you need to catch, and deal with that only. As you can see in the API
          documentation, find_element_by_link_text is documented to throw a NoSuchElementException if something fails. Catch that instead, so irrelevant errors aren't silently ignored as well:



          try:
          retry = browser.find_element_by_link_text('Try again')

          except NoSuchElementException as e: # Be specific!
          continue

          else:
          retry.click()


          Now anything other than a NoSuchElementException will cause your program to crash. This is a good thing though. You don't want fundamentally broken code to run.



          Don't make your code vulnerable to silly mistakes that may happen in the future. Silly mistakes happen (like improperly tested functions). It's best that they fail catastrophically so they can be detected and fixed.



          Of course though, the better option to handling the addition of do_something_with_retry would be, if possible, to just not group it in the try in the first place. Again though, mistakes happen.





          As for




          Currently it takes alot of tries to get a high score for the bot. Can the logic be improved?




          That involves writing up an AI to play the game, and is no small feat. That would be beyond the scope of a Code Review unfortunately.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 10 at 21:27

























          answered Dec 10 at 21:21









          Carcigenicate

          2,70811229




          2,70811229












          • if i define name 'NoSuchElementException' is not defined it is not defined
            – Sandro4912
            Dec 11 at 16:50










          • @Sandro4912 You need to import it from selenium. That's not a standard exception.
            – Carcigenicate
            Dec 11 at 16:52










          • it worked by adding from selenium.common.exceptions import NoSuchElementException
            – Sandro4912
            Dec 11 at 16:54




















          • if i define name 'NoSuchElementException' is not defined it is not defined
            – Sandro4912
            Dec 11 at 16:50










          • @Sandro4912 You need to import it from selenium. That's not a standard exception.
            – Carcigenicate
            Dec 11 at 16:52










          • it worked by adding from selenium.common.exceptions import NoSuchElementException
            – Sandro4912
            Dec 11 at 16:54


















          if i define name 'NoSuchElementException' is not defined it is not defined
          – Sandro4912
          Dec 11 at 16:50




          if i define name 'NoSuchElementException' is not defined it is not defined
          – Sandro4912
          Dec 11 at 16:50












          @Sandro4912 You need to import it from selenium. That's not a standard exception.
          – Carcigenicate
          Dec 11 at 16:52




          @Sandro4912 You need to import it from selenium. That's not a standard exception.
          – Carcigenicate
          Dec 11 at 16:52












          it worked by adding from selenium.common.exceptions import NoSuchElementException
          – Sandro4912
          Dec 11 at 16:54






          it worked by adding from selenium.common.exceptions import NoSuchElementException
          – Sandro4912
          Dec 11 at 16:54














          up vote
          1
          down vote













          A first step towards writing an AI is to give this an interface.



          First, let's rewrite the "AI" you are currently using as a class:



          from itertools import cycle

          class Cycler:
          def __init__(self):
          self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])

          def next(self, *args):
          return next(self.cycle)


          Which you can use like this in your current code:



          ai = Cycler()
          while True:
          html.send_keys(ai.next())
          try:
          ...


          In the future you might want to be smarter than that and for that you would need the state of the board to be passed along to the AI.



          Class GameStatePrinter(Cycler):
          def next(self, game_state, *args):
          print(game_state)
          return super(self, GameStatePrinter).next(*args)


          This is not really any smarter, but you can pass it the current game state and it will print it:



          ai = GameStatePrinter()
          while True:
          current_state = get_current_state(html)
          html.send_keys(ai.next(current_state))
          ...


          An actual smart bot would then of course act differently according to the information in the board, whereas this one just does the same thing as Cycler, which it inherits from.



          This logic is left as an exercise for the reader.






          share|improve this answer





















          • i tryed adding the first part but in the line self.cycle = cycle[Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN] it throws 'type' object is not subscriptable so maybe the keys don't work with cycler
            – Sandro4912
            Dec 11 at 17:05










          • @Sandro4912: You missed the parenthesis around the list, it should be self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])
            – Graipher
            Dec 11 at 17:07















          up vote
          1
          down vote













          A first step towards writing an AI is to give this an interface.



          First, let's rewrite the "AI" you are currently using as a class:



          from itertools import cycle

          class Cycler:
          def __init__(self):
          self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])

          def next(self, *args):
          return next(self.cycle)


          Which you can use like this in your current code:



          ai = Cycler()
          while True:
          html.send_keys(ai.next())
          try:
          ...


          In the future you might want to be smarter than that and for that you would need the state of the board to be passed along to the AI.



          Class GameStatePrinter(Cycler):
          def next(self, game_state, *args):
          print(game_state)
          return super(self, GameStatePrinter).next(*args)


          This is not really any smarter, but you can pass it the current game state and it will print it:



          ai = GameStatePrinter()
          while True:
          current_state = get_current_state(html)
          html.send_keys(ai.next(current_state))
          ...


          An actual smart bot would then of course act differently according to the information in the board, whereas this one just does the same thing as Cycler, which it inherits from.



          This logic is left as an exercise for the reader.






          share|improve this answer





















          • i tryed adding the first part but in the line self.cycle = cycle[Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN] it throws 'type' object is not subscriptable so maybe the keys don't work with cycler
            – Sandro4912
            Dec 11 at 17:05










          • @Sandro4912: You missed the parenthesis around the list, it should be self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])
            – Graipher
            Dec 11 at 17:07













          up vote
          1
          down vote










          up vote
          1
          down vote









          A first step towards writing an AI is to give this an interface.



          First, let's rewrite the "AI" you are currently using as a class:



          from itertools import cycle

          class Cycler:
          def __init__(self):
          self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])

          def next(self, *args):
          return next(self.cycle)


          Which you can use like this in your current code:



          ai = Cycler()
          while True:
          html.send_keys(ai.next())
          try:
          ...


          In the future you might want to be smarter than that and for that you would need the state of the board to be passed along to the AI.



          Class GameStatePrinter(Cycler):
          def next(self, game_state, *args):
          print(game_state)
          return super(self, GameStatePrinter).next(*args)


          This is not really any smarter, but you can pass it the current game state and it will print it:



          ai = GameStatePrinter()
          while True:
          current_state = get_current_state(html)
          html.send_keys(ai.next(current_state))
          ...


          An actual smart bot would then of course act differently according to the information in the board, whereas this one just does the same thing as Cycler, which it inherits from.



          This logic is left as an exercise for the reader.






          share|improve this answer












          A first step towards writing an AI is to give this an interface.



          First, let's rewrite the "AI" you are currently using as a class:



          from itertools import cycle

          class Cycler:
          def __init__(self):
          self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])

          def next(self, *args):
          return next(self.cycle)


          Which you can use like this in your current code:



          ai = Cycler()
          while True:
          html.send_keys(ai.next())
          try:
          ...


          In the future you might want to be smarter than that and for that you would need the state of the board to be passed along to the AI.



          Class GameStatePrinter(Cycler):
          def next(self, game_state, *args):
          print(game_state)
          return super(self, GameStatePrinter).next(*args)


          This is not really any smarter, but you can pass it the current game state and it will print it:



          ai = GameStatePrinter()
          while True:
          current_state = get_current_state(html)
          html.send_keys(ai.next(current_state))
          ...


          An actual smart bot would then of course act differently according to the information in the board, whereas this one just does the same thing as Cycler, which it inherits from.



          This logic is left as an exercise for the reader.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 11 at 13:08









          Graipher

          23.2k53384




          23.2k53384












          • i tryed adding the first part but in the line self.cycle = cycle[Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN] it throws 'type' object is not subscriptable so maybe the keys don't work with cycler
            – Sandro4912
            Dec 11 at 17:05










          • @Sandro4912: You missed the parenthesis around the list, it should be self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])
            – Graipher
            Dec 11 at 17:07


















          • i tryed adding the first part but in the line self.cycle = cycle[Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN] it throws 'type' object is not subscriptable so maybe the keys don't work with cycler
            – Sandro4912
            Dec 11 at 17:05










          • @Sandro4912: You missed the parenthesis around the list, it should be self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])
            – Graipher
            Dec 11 at 17:07
















          i tryed adding the first part but in the line self.cycle = cycle[Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN] it throws 'type' object is not subscriptable so maybe the keys don't work with cycler
          – Sandro4912
          Dec 11 at 17:05




          i tryed adding the first part but in the line self.cycle = cycle[Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN] it throws 'type' object is not subscriptable so maybe the keys don't work with cycler
          – Sandro4912
          Dec 11 at 17:05












          @Sandro4912: You missed the parenthesis around the list, it should be self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])
          – Graipher
          Dec 11 at 17:07




          @Sandro4912: You missed the parenthesis around the list, it should be self.cycle = cycle([Keys.RIGHT, Keys.UP, Keys.LEFT, Keys.DOWN])
          – Graipher
          Dec 11 at 17:07


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209386%2f2048-webgame-bot%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Список кардиналов, возведённых папой римским Каликстом III

          Deduzione

          Mysql.sock missing - “Can't connect to local MySQL server through socket”