I have written a python script that should automatically play the game 2048 (https://play2048.co/).
The problem is: keystrokes seem to be ignored by the browser. Or the program runs too fast for having the browser clicking through the game. I have checked the Selenium documentation and I am not sure if I have to include some explicit waits.
Here is my code:
#! python3 #_2048.py - A program that plays the game 2048 (https://play2048.co/) # automatically. from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC def assess_board(): tileContainer = browser.find_element(By.CLASS_NAME, 'tile-container') # finds the tile container tiles = tileContainer.find_elements(By.TAG_NAME, "div[class*='tile-position']") # finds every tile for tile in tiles: # maps all values in the board boardvalues.append(tile.get_attribute('class')[10]) def click(): # Performs a click (changes after every click: UP-RIGHT-DOWN-LEFT) if start % 4 == 1: print('up') Keys.UP elif start % 4 == 2: print('right') Keys.RIGHT elif start % 4 == 3: print('down') Keys.DOWN elif start % 4 == 0: print('left') Keys.LEFT browser = webdriver.Firefox() # Open Firefox browser.get('https://play2048.co/') # Go to https://play2048.co/ wait = WebDriverWait(browser, 10) boardvalues =[] number_of_clicks = 0 start = 1 while '2048' not in boardvalues: wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".game-container"))) click() number_of_clicks += 1 start += 1 assess_board() if len(boardvalues) == 16: print('You lost!') print('number of clicks: ', number_of_clicks) print('2048! You won!') print('number of clicks: ', number_of_clicks)
The goal of the game is reaching the score 2048 by sliding tiles upon eachother by hitting the arrow keys. The game is over when the square is full and you haven’t reached a 2048-tile.
I am not sure what happens during my while loop. The browser seems to ignore the keystrokes of the arrow keys. The tiles are not moved. Every simulated click on an arrow key should move the tiles.
What might be the problem here?
Code update
#! python3 #_2048.py - A program that plays the game 2048 (https://play2048.co/) # automatically. from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC import time def assess_board(): tileContainer = browser.find_element(By.CLASS_NAME, 'tile-container') # finds the tile container tiles = tileContainer.find_elements(By.TAG_NAME, "div[class*='tile-position']") # finds every tile for tile in tiles: # maps all values in the board boardvalues.append(tile.get_attribute('class')[10]) def click(): # Performs a click (changes after every click: UP-RIGHT-DOWN-LEFT) if start % 4 == 1: print('up') bodyElem.send_keys(Keys.UP) elif start % 4 == 2: print('right') bodyElem.send_keys(Keys.RIGHT) elif start % 4 == 3: print('down') bodyElem.send_keys(Keys.DOWN) elif start % 4 == 0: print('left') bodyElem.send_keys(Keys.LEFT) browser = webdriver.Firefox() # Open Firefox browser.get('https://play2048.co/') # Go to https://play2048.co/ bodyElem = browser.find_element(By.TAG_NAME, 'body') wait = WebDriverWait(browser, 10) boardvalues =[] number_of_clicks = 0 start = 1 while '2048' not in boardvalues: wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".game-container"))) click() time.sleep(0.5) number_of_clicks += 1 start += 1 assess_board() if len(boardvalues) == 16: print('You lost!') print('number of clicks: ', number_of_clicks) print('2048! You won!') print('number of clicks: ', number_of_clicks)
Advertisement
Answer
Your click()
function doesn’t actually click anything:
def click(): # Performs a click (changes after every click: UP-RIGHT-DOWN-LEFT) if start % 4 == 1: print('up') Keys.UP # ^^^^^^ ...
Your code here is just referencing Keys.UP
object. Instead, you need to find an element and send that key to it:
def click(): # Performs a click (changes after every click: UP-RIGHT-DOWN-LEFT) # main <body> tag acts as your element that controls the keys board = browser.find_element_by_css_selector('body') if start % 4 == 1: print('up') board.send_keys(Keys.UP) # ^^^^^^^^^^^