Chopsticks mutated with points KoTH

13

2

Basic rules (different from mine)

Story

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.

EX

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.

EX

P1: 1000,2 P2 7,7. P2[0] hitsP1[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)

Endgame

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

Handler

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.

Tada!

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.

Christopher

Posted 2017-07-19T15:50:22.163

Reputation: 3 428

Sandbox – Christopher – 2017-07-19T15:50:40.383

Could "Standard KOTH rules" be a link? And maybe "Standard loopholes" too. – trichoplax – 2017-07-19T15:52:01.837

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? – HyperNeutrino – 2017-07-19T15:53:19.217

@HyperNeutrino opps fixing. – Christopher – 2017-07-19T15:54:29.783

@Christopher Where is bot1split defined? Your controller isn't going to work. – HyperNeutrino – 2017-07-19T16:20:01.673

@HyperNeutrino sorry copy paste error – Christopher – 2017-07-19T16:21:04.187

This makes it impossible to split. Python is pass-by-reference, but if you redefine a function parameter, it will just change the local reference. Your controller still won't work. – HyperNeutrino – 2017-07-19T16:22:23.297

@HyperNeutrino screw python. How do I fix that? – Christopher – 2017-07-19T16:22:43.557

@Christopher Hold on, I'll rewrite the controller in a bit. I don't like the hardcoding of the function names either, so I'll send teh codez in a bit. – HyperNeutrino – 2017-07-19T16:23:33.340

@HyperNeutrino I owe you one :P ty so much. I suck at writing this codez – Christopher – 2017-07-19T16:29:39.407

@Arnauld thanks – Christopher – 2017-07-19T17:35:18.187

4Dennis has more rep than Martin now. Oh my god, where did these extra 996 fingers come from?! – caird coinheringaahing – 2017-07-19T23:16:47.710

@cairdcoinheringaahing we have no idea. I am so sorry. – Christopher – 2017-07-20T02:10:28.923

The post says "Points are scored by the amount of fingers the winner has," but the controller you link to only records win/losses when I run it. Is this intended or did I do something wrong here? – Magenta – 2017-07-23T13:47:53.370

@mag hmm looking into that. I actually have a few things to do with it first. But I will fix it – Christopher – 2017-07-23T15:12:45.283

I would VTC this as unclear because of the controller issues, but apparently that's impossible if there's a bounty running. So count this as a virtual VTC from me. – Mego – 2017-07-25T22:51:54.870

@Mego controller issues? Also Virtual VTO – Christopher – 2017-07-25T23:27:02.450

@Christopher As Magenta mentioned, the scoring in the controller doesn't match the scoring in the description. – Mego – 2017-07-25T23:28:03.870

@Mego OH, I have a version for scores. I didn't provide it since I did not think people needed to know. I will update – Christopher – 2017-07-25T23:38:01.430

@Christopher You didn't think people would need a controller that matches the spec? – Mego – 2017-07-26T00:54:25.067

@Mego I didn't think – Christopher – 2017-07-26T16:23:33.913

Answers

6

CodingAndAlgorithms

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)]
    else:
        return [A.index(min(A)), B.index(min(B))]

betseg

Posted 2017-07-19T15:50:22.163

Reputation: 8 493

I got that reference XD – Christopher – 2017-07-28T23:42:29.010

This just won. It never lost. – Christopher – 2017-07-29T23:46:08.057

Congratulations! I guess I'm going to have to settle for second place. Your coding and algorithms were stronger than mine – Value Ink – 2017-08-01T00:43:05.047

3

Aggressor

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.

HyperNeutrino

Posted 2017-07-19T15:50:22.163

Reputation: 26 575

3

CautionBot

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))]
 else:
  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.

Value Ink

Posted 2017-07-19T15:50:22.163

Reputation: 10 608

Unofficially this is winning – Christopher – 2017-07-23T21:47:09.180

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 – Value Ink – 2017-07-23T22:58:12.693

3

Equalizer

def play(s, o):
    if not all(s):
        return 1
    else:
        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.

LyricLy

Posted 2017-07-19T15:50:22.163

Reputation: 3 313

According to these mutated rules, AFAIK you can only split if one hand is out. – Value Ink – 2017-07-20T04:25:52.567

Oh yeah, I'll fix that. – LyricLy – 2017-07-20T04:26:15.947

"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 – Value Ink – 2017-07-20T04:33:10.290

2

RandomBot

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

HyperNeutrino

Posted 2017-07-19T15:50:22.163

Reputation: 26 575

I was fixing that – Christopher – 2017-07-19T15:55:54.417

@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 – HyperNeutrino – 2017-07-19T15:56:25.793

@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 :) – HyperNeutrino – 2017-07-19T21:27:53.290

Nice trying them out – Christopher – 2017-07-19T21:32:03.363

@Christopher Does the controller work properly? – HyperNeutrino – 2017-07-19T21:33:33.677

Getting it set up rn – Christopher – 2017-07-19T21:35:07.697

Let us continue this discussion in chat.

– Christopher – 2017-07-19T21:36:04.890

Please don't __import__('random') inside a loop. That's a lot of efficienty percents lost compared to import random then using random. – Uriel – 2017-07-23T19:17:56.977

@Uriel right yes, thanks. – HyperNeutrino – 2017-07-23T19:18:24.653

@HyperNeutrino here this wouldn't make much of a change, because it's just 2 calls every round, but in general... – Uriel – 2017-07-23T19:20:13.387

golfed more. play = lambda s,o:[random.randint(0,1)for i in' ']if all(s)else 1 – Destructible Lemon – 2017-07-24T03:28:26.803

@DestructibleLemon Unfortunately the lambda doesn't seem to work because it seems to not be a publicly accessed function. I don't know the details, but it didn't work as a lambda. – HyperNeutrino – 2017-07-24T10:26:03.207

2

Error

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.

Magenta

Posted 2017-07-19T15:50:22.163

Reputation: 1 322

1

Marathoner

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

Jordan

Posted 2017-07-19T15:50:22.163

Reputation: 31

Nice first answer! You chose a great question :P (no bias) – Christopher – 2017-07-27T16:47:34.973

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 – Jordan – 2017-07-27T17:27:50.990

Yeah. On this SE tweaking code is often used :P – Christopher – 2017-07-27T18:59:43.770

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. – Value Ink – 2017-07-27T19:56:49.273

@ValueInk Hmm. I understand what you're saying. I'll try some fiddling but I don't think this oversight will be a huge problem because this is probably (besides doing nothing) the worst strategy haha

Also thanks for the support on my answer, first one and all. Hopefully I'll be outgolfing you in a few months ;) – Jordan – 2017-07-27T20:11:12.047

Isn't this what my bot, Equalizer, does anyway? – LyricLy – 2017-07-28T22:42:28.067

1This is very similar to Equalizer but Equalizer will check to make sure it doesn't hit the opponent's empty hand if present. @LyricLy – HyperNeutrino – 2017-07-28T23:47:48.363