daily pastebin goal
59%
SHARE
TWEET

main.py - Twitch Plays Chess Bot

WiesenWiesel Apr 3rd, 2015 (edited) 411 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # V 0.2 - 04/02/2015 - Feel free to follow me: http://twitter.com/WeaselZone
  2.  
  3. #Define the imports
  4. import twitch
  5. import win32api
  6. import win32con
  7. import win32com.client as comclt
  8. import time
  9. import urllib  # for getting data from URL
  10. import json  # parsing json
  11. import re
  12. import ctypes
  13. import datetime
  14.  
  15. t = twitch.Twitch()  # Reference the twitch script
  16.  
  17. username = "weasel_9000"  # The username of your bot
  18. channel = "weasel_9000"  # The channel you want your bot to be in
  19. key = "oauth:XXXXXXXXXXXXXXXXXXX"  # oauth-key can be generated at http://twitchapps.com/tmi/
  20.  
  21. game = "chess"
  22.  
  23. restart_vote_time = 5  # The length of the restart vote
  24.  
  25. # Chess variables
  26. board_coordinates = [57, 154, 600, 690]  # upper corner X, Y to lower corner x & y (Lucas Chess)
  27. field_size = (board_coordinates[2] - board_coordinates[0]) / 8
  28.  
  29. # Let's connect to Twitch
  30. t.twitch_connect(username, key, channel)
  31.  
  32. shell = None;
  33.  
  34. def key_press(key):
  35.     shell = comclt.Dispatch("WScript.Shell")
  36.     shell.SendKeys(key)
  37.  
  38. # click(10,10)
  39. def click(x, y):
  40.     ctypes.windll.user32.SetCursorPos(x, y)
  41.     win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)  # Left Button Down
  42.     win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)  # Left Button Up
  43.  
  44. def mouse_move(x, y):
  45.     ctypes.windll.user32.SetCursorPos(x, y)
  46.  
  47.  
  48. # drag(10,10,20,20)
  49. def drag(startX, startY, endX, endY):
  50.     ctypes.windll.user32.SetCursorPos(startX, startY)
  51.     time.sleep(0.2)
  52.     win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, startX, startY, 0, 0)  # Left Button Down
  53.     ctypes.windll.user32.SetCursorPos(endX, endY)
  54.     time.sleep(0.2)
  55.     win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, endX, endY, 0, 0)  # Left Button Up
  56.     mouse_move(1, 1) # Move mouse out of window
  57.  
  58.  
  59. def is_moderator(user):
  60.     url = "http://tmi.twitch.tv/group/user/" + channel + "/chatters"  # Getting a list of users
  61.     response = urllib.urlopen(url)
  62.     data = json.loads(response.read())
  63.     # print data;  # Output the whole response
  64.     chatters = data['chatters']
  65.     moderators = chatters['moderators']
  66.     for x in moderators:  # Going through the current moderators
  67.         if user == x:
  68.             return True
  69.     return False
  70.  
  71. # ===========================================================
  72. # ======================= CHESS =============================
  73. # ===========================================================
  74.  
  75. def chess_restart():
  76.     # These commands are for 'Lucas Chess' and have to be adjusted to your program
  77.     click(100, 5)  # Click in the window to focus it
  78.     time.sleep(0.2)
  79.     key_press("{ENTER}")
  80.     time.sleep(0.2)
  81.     key_press("{ENTER}")
  82.     click(450, 60)  # Click 'Reinit' Button
  83.     time.sleep(1.3)
  84.     key_press("{ENTER}")
  85.     time.sleep(4)
  86.     key_press("{ESC}")  # Close the potentially open Tutor window -.-
  87.     time.sleep(0.2)
  88.     key_press("{ENTER}")
  89.     time.sleep(0.2)
  90.     key_press("{ENTER}")
  91.     mouse_move(1, 1) # Move mouse out of the window
  92.     print "DONE: Game restarted."
  93.     t.send_message(channel, 'The game has been restarted. If the game does not react to commands, try !newgame again.')
  94.  
  95. #The main loop for chess
  96. if game == "chess":
  97.  
  98.     restart_vote_start = 0
  99.     restart_vote = 0
  100.     restart_votes_yes = 0
  101.     restart_votes_no = 0
  102.     restart_vote_username = ""
  103.  
  104.     while True:
  105.  
  106.         # Check for active votes
  107.         if restart_vote == 1:
  108.             if datetime.datetime.now()-restart_vote_start >= datetime.timedelta(seconds=restart_vote_time):
  109.                 t.send_message(channel, 'Vote ended, here are the results: Yes - ' + str(restart_votes_yes) + ' vote(s), '
  110.                                         'No ' + str(restart_votes_no) + ' - vote(s)')
  111.                 if restart_votes_yes > restart_votes_no:
  112.                     print 'DONE: Vote successful! Restarting the game. Please wait a few seconds.'
  113.                     t.send_message(channel, 'Vote successful. Restarting the game!')
  114.                     chess_restart()
  115.                     restart_vote = 0
  116.                     restart_vote_username = ''
  117.                 else:
  118.                     print 'DONE: Vote failed! Not restarting.'
  119.                     t.send_message(channel, 'Vote failed! Not restarting.')
  120.                     restart_vote = 0
  121.  
  122.         # Check for new messages
  123.         new_messages = t.twitch_receive_messages();
  124.  
  125.         if not new_messages:
  126.             # No new messages...
  127.             continue
  128.         else:
  129.             for message in new_messages:
  130.                 # Got new message
  131.                 msg = message['message'].lower()
  132.                 username = message['username'].lower()
  133.                 print("Message from "+username + ": " + msg)
  134.  
  135.  
  136.  
  137.                 # Moderator-only commands:
  138.                 if is_moderator(username):
  139.                     if msg == "!restart":  # Restart the current game (forced)
  140.                         print username+" is a moderator, accepting !restart command.";
  141.                         chess_restart()
  142.                         restart_vote = 0
  143.                         restart_vote_username = ""
  144.  
  145.  
  146.                 # Global commands
  147.  
  148.                 if msg.startswith('!help'):
  149.                         t.send_message(channel, "To make a move, enter !move and the starting field followed by "
  150.                                                 "the destination field i.e. '!move a2 a3'. To start the vote for a "
  151.                                                 " new game, enter !newgame.")
  152.  
  153.                 if msg.startswith('!accept'):
  154.                         key_press("{ENTER}")
  155.                         time.sleep(0.2)
  156.                         key_press("{ESC}")
  157.  
  158.                 if msg.startswith('!decline'):
  159.                         key_press("{ESC}")
  160.  
  161.                 #Starting the vote for a new game
  162.                 if msg.startswith('!newgame'):
  163.                         if restart_vote_username == username:
  164.                             t.send_message(channel, username + ', your last vote failed, '
  165.                                                                'you cannot start a new vote.')
  166.                         else:
  167.                             t.send_message(channel, username + ' wants to start a new game.'
  168.                                            'Type "!yes" or "!no" to vote! within the next '
  169.                                            + str(restart_vote_time) + ' seconds.')
  170.                             restart_vote_username = username  # Set the current user as the person who started it
  171.                             restart_vote = 1  # Activate the vote countdown
  172.                             restart_votes_yes = 1  # Reset the votes
  173.                             restart_votes_no = 0
  174.                             restart_vote_start = datetime.datetime.now() # Save current time
  175.                             print "DONE: Started new vote."
  176.  
  177.                 if msg == '!yes' and username != restart_vote_username:
  178.                     if restart_vote == 1:
  179.                         restart_votes_yes += 1
  180.                         print "DONE: Vote cast. (yes)"
  181.  
  182.                 if msg == '!no' and username != restart_vote_username:
  183.                     if restart_vote == 1:
  184.                         restart_votes_no += 1
  185.                         print "DONE: Vote cast. (no)"
  186.  
  187.                 if msg.startswith('!move'):
  188.                     print "Move command"
  189.                     split = msg.split(' ')
  190.                     if len(msg) == 11 and len(split[0]) == 5 and len(split[1]) == 2 and len(split[2]) == 2:
  191.                         print "Move from " + split[1] + " to " + split[2]
  192.  
  193.                         print split[1][0] + "," + split[1][1]
  194.  
  195.                         print split[2][0] + "," + split[2][1]
  196.  
  197.                         # Are letters & numbers valid?
  198.                         if re.match("^[A-Ha-h]*$", split[1][0]) and re.match("^[A-Ha-h]*$", split[2][0]) \
  199.                                 and re.match("^[1-8]*$", split[1][1]) and re.match("^[1-8]*$", split[2][1]):
  200.  
  201.                             # Executing move command
  202.                             print "All ok. Executing command."
  203.  
  204.                             field_start_x = 1
  205.                             field_start_y = 1
  206.                             field_end_x = 1
  207.                             field_end_y = 1
  208.  
  209.                             # Get field
  210.                             if re.match("^[Aa]*$", split[1][0]):
  211.                                 field_start_x = 1
  212.                             if re.match("^[Bb]*$", split[1][0]):
  213.                                 field_start_x = 2
  214.                             if re.match("^[Cc]*$", split[1][0]):
  215.                                 field_start_x = 3
  216.                             if re.match("^[Dd]*$", split[1][0]):
  217.                                 field_start_x = 4
  218.                             if re.match("^[Ee]*$", split[1][0]):
  219.                                 field_start_x = 5
  220.                             if re.match("^[Ff]*$", split[1][0]):
  221.                                 field_start_x = 6
  222.                             if re.match("^[Gg]*$", split[1][0]):
  223.                                 field_start_x = 7
  224.                             if re.match("^[Hh]*$", split[1][0]):
  225.                                 field_start_x = 8
  226.  
  227.                             # Numbers need to be flipped (Lucas Chess start with 8 down to 1 by default)
  228.  
  229.                             if split[1][1] == "8":
  230.                                 field_start_y = 1
  231.                             if split[1][1] == "7":
  232.                                 field_start_y = 2
  233.                             if split[1][1] == "6":
  234.                                 field_start_y = 3
  235.                             if split[1][1] == "5":
  236.                                 field_start_y = 4
  237.                             if split[1][1] == "4":
  238.                                 field_start_y = 5
  239.                             if split[1][1] == "3":
  240.                                 field_start_y = 6
  241.                             if split[1][1] == "2":
  242.                                 field_start_y = 7
  243.                             if split[1][1] == "1":
  244.                                 field_start_y = 8
  245.  
  246.  
  247.                             if re.match("^[Aa]*$", split[2][0]):
  248.                                 field_end_x = 1
  249.                             if re.match("^[Bb]*$", split[2][0]):
  250.                                 field_end_x = 2
  251.                             if re.match("^[Cc]*$", split[2][0]):
  252.                                 field_end_x = 3
  253.                             if re.match("^[Dd]*$", split[2][0]):
  254.                                 field_end_x = 4
  255.                             if re.match("^[Ee]*$", split[2][0]):
  256.                                 field_end_x = 5
  257.                             if re.match("^[Ff]*$", split[2][0]):
  258.                                 field_end_x = 6
  259.                             if re.match("^[Gg]*$", split[2][0]):
  260.                                 field_end_x = 7
  261.                             if re.match("^[Hh]*$", split[2][0]):
  262.                                 field_end_x = 8
  263.  
  264.                             # Numbers need to be flipped (Lucas Chess start with 8 down to 1 by default)
  265.  
  266.                             if split[2][1] == "8":
  267.                                 field_end_y = 1
  268.                             if split[2][1] == "7":
  269.                                 field_end_y = 2
  270.                             if split[2][1] == "6":
  271.                                 field_end_y = 3
  272.                             if split[2][1] == "5":
  273.                                 field_end_y = 4
  274.                             if split[2][1] == "4":
  275.                                 field_end_y = 5
  276.                             if split[2][1] == "3":
  277.                                 field_end_y = 6
  278.                             if split[2][1] == "2":
  279.                                 field_end_y = 7
  280.                             if split[2][1] == "1":
  281.                                 field_end_y = 8
  282.  
  283.                             # Calculate coordinates
  284.  
  285.                             move_start_x = board_coordinates[0] + (field_start_x * field_size) - (field_size/2)
  286.                             move_start_y = board_coordinates[1] + (field_start_y * field_size) - (field_size/2)
  287.  
  288.                             move_end_x = board_coordinates[0] + (field_end_x * field_size) - (field_size/2)
  289.                             move_end_y = board_coordinates[1] + (field_end_y * field_size) - (field_size/2)
  290.  
  291.                             print str(field_start_x) + "," + str(field_start_y) + "," + str(field_end_x) + "," + str(field_end_y)
  292.                             print str(move_start_x) + "," + str(move_start_y) + "," + str(move_end_x) + "," + str(move_end_y)
  293.  
  294.                             # Doing the move
  295.                             click(35, 125)  # Click in the window to focus it
  296.                             drag(move_start_x, move_start_y, move_end_x, move_end_y)
  297.  
  298.                             print "DONE: Command executed."
  299.  
  300.  
  301.                         else:
  302.                             print "BAD COMMAND: Wrong coordinates"
  303.                             t.send_message(channel, username + ': Coordinates are invalid, please check your command.')
  304.  
  305.                     else:
  306.                         print "BAD COMMAND: Length command incorrect"
  307.                         t.send_message(channel, username + ': Command invalid. Example: !move b2 b4')
RAW Paste Data
Top