daily pastebin goal
56%
SHARE
TWEET

main.py - Twitch Plays Chess Bot

WiesenWiesel Apr 3rd, 2015 (edited) 447 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top