I made a bot that reads your mind. It records your sequence of plays and predicts your next move based on similar past sequences. If you try to play randomly then it will win significantly more frequently than you because you are bad at being random. If you feed it an actual random sequence of moves (as a test to be sure it isn’t cheating) then it will not win more frequently.
Well seeing as you can calculate what its next move is going to be based on what your past moves has been, you can beat it 100% of the time. The better challenge would be to make it better at predicting.
The winning pattern is that you do the opposite of the expected pattern. The bot learns the expected pattern from repetition. If you just simulate the bot and play against what it is going to do then you will always win.
local strings={}
local signal=game.ReplicatedStorage.Signal
signal.OnServerInvoke=function(player,move)
local s=strings[player.UserId]or''
local a,b,c,p=0,0,0,''
for i=1,#s do
local A,B,C=a,b,c
local v=3^i
for _ in s:gmatch("0"..p)do a=a+v end
for _ in s:gmatch("1"..p)do b=b+v end
for _ in s:gmatch("2"..p)do c=c+v end
if a==A and b==B and c==C then break end
p=p..s:sub(i,i)
end
local response
if a>b and a>c then response=1
elseif b>a and b>c then response=2
elseif c>a and c>b then response=0
elseif a>b and a==c then response=0
elseif b>c and b==a then response=1
elseif c>a and c==b then response=2
else response=math.random(3)-1 end
strings[player.UserId]=move..s
if(move==0 and response==1)or(move==1 and response==2)or(move==2 and response==0)then return false end
if move~=response then return true end
end
It records your plays. rock/paper/scissors are encoded as 0/1/2 and the string of everything you have done is searched for copies of the current last few moves. It searches through every length and predicts that your next move is going to be the same next move that you made then. Longer matches are weighted higher, so if you played the exact same sequence of 10 moves previously then it is probably going to predict that your next move is going to be the 11th move in that previous sequence.
I’ve made it slightly more accurate by reducing the value of older repetitions, so when it finds something at point “x” in the string, it divides the value of that repetition (3^length) by x.
also now you can choose rock/paper/scissors by pressing 1/2/3 on your keyboard instead of clicking on them.
key mashing lets you press buttons a lot faster
This is quite ingenious. Unless people are using complex mental algorithms or random number generators, it seems only logical that they would recall patterns that seem random to them, but are actually just repeated sequences of past patterns in memory. Give an AI time to analyze these patterns, well, the numbers speak for themselves.
I wonder if there is any way to improve the ability for the AI to predict old patterns beyond simple sequences of choices.
Repetition is a good generalization. If you choose rock a ton more than you choose scissors then it is going to choose paper a lot more frequently. If you have a tendency of choosing paper every time after you choose rock, it will choose scissors every game after you choose rock. If you have a habit of some other longer sequence then it will follow that one instead if it sees that you’re blatantly repeating yourself. What it wouldn’t see would be if you were actively avoiding repetitive behavior. That would cause you to beat it.
Now that you’ve released your AI’s algorithm, I want to write my own AI which knows what data has been recorded by your AI, and will specifically attempt to beat your AI and its patterns of trying to guess my patterns, and then countering that guess.
You could model it as a group of estimators for certain lengths, and estimate the mean/variance of the predictions of each. From here you could generate a random number and select a viable estimator at random based on some function of the mean and variance. It probably makes sense to stop after a suitable window size as I get the feeling the variance of very long sequences would be quite high. If this is the case, you can just keep track of all subsequences of length N.
There is probably a handful of tuning parameters and bias-variance tradeoffs. For example, having some estimator based on the specific subsequence seen vs all sequences of that length.
There might also be some additional estimators based on assumptions that some patterns are more/less likely to occur if they previously resulted in success/failure.