Basic rules (different from mine)


It is the year 4579, humans now have 2 hands with 1001 fingers each. Chopsticks has become based off of points. And @Dennis has more rep then @Martin... Hand drawn red circles are now downvoted... Jon Skeet has hit 2 trillion rep on every SE site... Yeah scary I know

Chopsticks is a hand game that has been solved. So to get around this I have created it mutated. I increased the amount of fingers.

Rules of the game

The way this is played

Everyone starts with 2 hands. Each hand has 1001 fingers. Every hand starts with 1 (one) finger up on each hand. During your turn you can "hit" the other players hand. To hit you choose 1 of your hands to hit with and 1 of their hands to hit. The hand that was hit now has the amount of fingers that was their at first AND the amount of fingers that you had on the hand you hit with.


P1: 1,1 P2: 1,1. P1[0] hits P2[1]. Now fingers are P1:1,1 P2:1,2. Now P2[1] hits p1[0]. The fingers are now P1: 3,1 P2 1,2.

If one hand gets to 1001 fingers up or more then that hand is out. Then player who got a hand out (for their turn) can "split". Splitting is when you take the hand that is in and halve the amount of fingers (round up) and give those fingers to the other hand getting it back in.


P1: 1000,2 P2 7,7. P2[0] hits P1[0]. Score is P1: 0,2 P2 1,1. P1[1] splits for his turn and the score is P1: 1,1 and P2 7,7.

The game ends when one player has both hands out. Points are scored by the amount of fingers the winner has. More points = better. The loser gains no points.

There are other rules that are used but these are the ones used here.

Everybody plays everybody (round robin)


Total your points up from every round you win. Then average everybody's points up. Divide your total by the average points and get your final score. Most points win.

Actual rules

Standard loopholes

Please do not try to solve the game. I actually have to be able to run it :P

Make sure the bot can run fast. With the length of rounds judging this will take a while

All libraries needed in your program must be in the default python library. Also list the ones you need imported. Imports will just be the basic import (for math I do: import math)

Answers must work in Python 3.x


Your bot will be its own Python 3 file with a play function.

play will be passed two lists of two numbers each. This number indicates how many fingers are up on each hand. The first list is your own hand.

If you choose to hit the other player's hand, then return a list of two bits. The first bit is the index of the hand you are using to hit (0 for the first, 1 for the last), and the second bit is the index of the hand you are hitting on the opponent.

If you choose to split, return any other truthy value.


The controller can be found here. Save each bot in its own file and list each bot's filename (without .py) in botnames.

Final note:

You and the other bot will take turns going first. If the game does not terminate in 100,000 (one hundred thousand) rounds, the game will be terminated and neither bot wins.

The controller is not protected against moves taking forever, but unnecessary overhead will be strongly frowned upon.

  • \$\begingroup\$ Sandbox \$\endgroup\$ – Christopher Jul 19 '17 at 15:50
  • \$\begingroup\$ Could "Standard KOTH rules" be a link? And maybe "Standard loopholes" too. \$\endgroup\$ – trichoplax Jul 19 '17 at 15:52
  • \$\begingroup\$ My handler is very simple, your bot must do it's logic then adjust the the finger scores as needed, remember! What, so we're the ones doing the computations for the KoTH? \$\endgroup\$ – hyper-neutrino Jul 19 '17 at 15:53
  • \$\begingroup\$ @HyperNeutrino opps fixing. \$\endgroup\$ – Christopher Jul 19 '17 at 15:54
  • 4
    \$\begingroup\$ Dennis has more rep than Martin now. Oh my god, where did these extra 996 fingers come from?! \$\endgroup\$ – caird coinheringaahing Jul 19 '17 at 23:16


This answer actually uses coding and algorithms, unlike the others so far!reference: imgur(also beats all of the answers posted before this)

def play(A, B):
    if sum(A) == 1:
        return [A.index(1), B.index(max(B))]
    elif max(A) + max(B) > 1000:
        return [A.index(max(A)), B.index(max(B))]
    elif 0 in A:
        return 1
    elif 0 in B:
        return [A.index(min(A)), 1-B.index(0)]
        return [A.index(min(A)), B.index(min(B))]
  • \$\begingroup\$ I got that reference XD \$\endgroup\$ – Christopher Jul 28 '17 at 23:42
  • \$\begingroup\$ This just won. It never lost. \$\endgroup\$ – Christopher Jul 29 '17 at 23:46
  • \$\begingroup\$ Congratulations! I guess I'm going to have to settle for second place. Your coding and algorithms were stronger than mine \$\endgroup\$ – Value Ink Aug 1 '17 at 0:43


def play(s,o):
 if max(s)+max(o)>1000 and (all(s) or max(s)+min(o)<1001):
  return [s.index(max(s)),o.index(max(o))]
  return [s.index(min(s)),o.index(min(filter(bool,o)))]if all(s) else 'split'

CautionBot doesn't want to cause too much trouble, so it hits the smaller of the opponent's hands with its smaller hand if it has both hands, and otherwise splits. However, CautionBot is no fool, so if it can take out an opponents' hand without immediately losing next turn, it will do so instead of its normal move.

  • \$\begingroup\$ Unofficially this is winning \$\endgroup\$ – Christopher Jul 23 '17 at 21:47
  • \$\begingroup\$ Cool! We'll see how things go from here because I won't be surprised when someone develops a better strategy. I just applied what I understood to be vanilla Chopstick strategy (be a coward and split often to avoid being killed) in a way that best accommodated the new rules (be a coward and hit low to avoid getting killed, since splitting/merging while you have both of your hands is illegal) lol \$\endgroup\$ – Value Ink Jul 23 '17 at 22:58


def play(s, o):
    if not all(s):
        return 1
        return [s.index(max(s)), o.index(min(filter(bool, o)))]

If Equalizer is missing a hand, it will split. Otherwise, it hits its opponents smallest hand with its own largest hand.

  • \$\begingroup\$ According to these mutated rules, AFAIK you can only split if one hand is out. \$\endgroup\$ – Value Ink Jul 20 '17 at 4:25
  • \$\begingroup\$ Oh yeah, I'll fix that. \$\endgroup\$ – LyricLy Jul 20 '17 at 4:26
  • \$\begingroup\$ "If Equalizer has no hands..." well I mean if it has no hands then it lost already? But that's just nitpicking, take my +1 to compensate \$\endgroup\$ – Value Ink Jul 20 '17 at 4:33


def play(s, o):
    return [s.index(max(s)),o.index(max(o))]if all(s)else 1

Another starter bot, Aggressor will hit the larger of the opponent's hands with the larger of its own hands if both of its hands are non-empty; otherwise, it splits.



import random

def play(s, o):
    return [random.randint(0,1)for i in'  ']if all(s)else 1

Just to get things started, here's a bot which makes a random hit if its hands are both non-empty; otherwise, splits.

Golfed because why not :3

  • \$\begingroup\$ I was fixing that \$\endgroup\$ – Christopher Jul 19 '17 at 15:55
  • \$\begingroup\$ @Christopher Sorry, didn't see your comment. ---Once you fix it I'll delete this.--- I'll just delete this because it's stupid xD \$\endgroup\$ – hyper-neutrino Jul 19 '17 at 15:56
  • \$\begingroup\$ @Christopher Note: I've edited this into a valid submission. I'll add another solution too; tell me if the controller doesn't work properly :) \$\endgroup\$ – hyper-neutrino Jul 19 '17 at 21:27
  • \$\begingroup\$ Nice trying them out \$\endgroup\$ – Christopher Jul 19 '17 at 21:32
  • \$\begingroup\$ @Christopher Does the controller work properly? \$\endgroup\$ – hyper-neutrino Jul 19 '17 at 21:33


Yes, that is the name of the bot.

def play(s, o):
    if max(s)+max(o)>1000:
        return [s.index(max(s)),o.index(max(o))]
    if 0 in s:return ''
    return [s.index(max(s)),o.index(min(o))]

I arrived at at this by testing with the other bots. However it is consistently second-last in my simulations. So Ill be making another bot eventually.

Edit: I can't seem to write any bot that beats CautionBot, and my extra testing seems to indicate that this is second best, not second worst.



I tweaked Aggressor's code provided by "HyperNeutrino" to simply hit the smaller of the opponents two hands with the smaller of it's hands. It is a very silly strategy of course but I can't turn down being at the top of a chart! (Even though that chart would be losses)

I'm not sure if this code will run without errors because I was unable to test it due to being at work. However, it should run flawlessly.

def play(s, o):
     return [s.index(min(s)),o.index(min(o))]if all(s)else 1
  • \$\begingroup\$ Nice first answer! You chose a great question :P (no bias) \$\endgroup\$ – Christopher Jul 27 '17 at 16:47
  • \$\begingroup\$ Thanks :) I was pretty nervous because I wasn't sure if tweaking someone else's code like I did was allowed or not. I assume it is as long as you make it obvious. And I was gonna try to make one that would just play the biggest hand against the opponents biggest but HyperNeutrino beat me to that one exactly! haha \$\endgroup\$ – Jordan Jul 27 '17 at 17:27
  • \$\begingroup\$ Yeah. On this SE tweaking code is often used :P \$\endgroup\$ – Christopher Jul 27 '17 at 18:59
  • \$\begingroup\$ Cool answer! One thing that I'd worry about (can't test it right now) is that I don't know how the controller will respond if you try to hit an empty hand, or how that factors into the rules. \$\endgroup\$ – Value Ink Jul 27 '17 at 19:56
  • 1
    \$\begingroup\$ This is very similar to Equalizer but Equalizer will check to make sure it doesn't hit the opponent's empty hand if present. @LyricLy \$\endgroup\$ – hyper-neutrino Jul 28 '17 at 23:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.