Pergunta

Please excuse any mistakes, this is my first post! Recently I was bored and was trying to make a batch script clone of an arcade game I once saw: http://antikrish.com/2013/01/28/whittakers-ascot-gold-cup-horse-racing-arcade-game/

Rules

I couldn’t remember the rules and wanted it to be fair so made my own.

  • Each horse has a number between 1 and 6
  • This number (x) is the chance of the horse moving each turn (1/x)
    • Horse 1 = 1/1 so moves every turn
    • Horse 3 = 1/3 so moves every three turns on average
    • Horse 6 = 1/6 so moves every six turns on average
  • This number (x) also dictates how are along the board the horse moves
    • Horse 1 = 1 space per move
    • Horse 3 = 3 spaces per move
    • Horse 6 = 6 spaces per move
  • The game board is 60 spaces long, the first horse/s to reach 60 are the winners (draws are allowed). 60 was chosen as a goal as it is a common multiple of 1, 2, 3, 4, 5 and 6.
  • The idea of this is that it should take each horse approximately 60 turns to reach the end and win.
    • Horse 1 => 60 spaces / 1 moves = 60 turns, 60 turns / (1/1) = 60 turns
    • Horse 3 => 60 spaces / 3 moves = 20 turns, 20 turns / (1/3) = 60 turns
    • Horse 6 => 60 spaces / 6 moves = 10 turns, 10 turns / (1/6) = 60 turns

Problem

I ran the game and everything seemed good! Except after a while I noticed Horse 1 almost never seemed to win. Now this could be explained with probability but I wanted to check, so I altered my code to keep track of the results over time and saw that the higher numbered horses were winning consistently more often!

I’ve uploaded a graph (http://i.imgur.com/IZuXnye.png) showing the results of the winners of three sets of 1000 races, where draws are allowed (and count as a win for all that finished). Now this behaviour isn’t necessarily a bad thing and means odds can be attached to each horse, however I am confused as to why it’s happening.

Reasons

In my mind there are three reasons for why this behaviour may be occurring:

  • I have a bug in my program. I’ve included the code below if you're interested.
  • Batch random is attached to time, and this is screwing the results making the higher numbers more likely. To test this I collected three sets of 1000 random numbers between 1 and 6 and the results seem alright.
    • Note I varied the time between the numbers being generated:
    • REM – no time gap between generation
    • 0 Sec – 0 seconds on timeout (so a brief pause)
    • 1 Sec – 1 second on timeout
  • This is an attribute of probability and payoffs, and the logic I’ve used is flawed for a fair game.

So, can anyone enlighten me as to why this may be happening?

Thanks in advance!

Here is the code if helpful:

@ECHO OFF
COLOR 0B
setlocal EnableDelayedExpansion
set total = 0
set totalscore[0]=0
set totalscore[1]=0
set totalscore[2]=0
set totalscore[3]=0
set totalscore[4]=0
set totalscore[5]=0
set totalscore[6]=0

:START
set /a total = total + 1
set score[0]=0
set score[1]=0
set score[2]=0
set score[3]=0
set score[4]=0
set score[5]=0
set score[6]=0
set winner=0

:LOOP
cls
echo Race Number: %total%
for /l %%n in (1,1,6) do (
    set /a num=!random! %%%%n + 1
    IF !num! == %%n set /a score[%%n]=!score[%%n]! + !num!
    <NUL set /p=%%n: 
    for /l %%x in (1, 1, !score[%%n]!) do <NUL set /p=^|
    set /a sum=60 - !score[%%n]!
    for /l %%x in (1, 1, !sum!) do <NUL set /p=_
    echo F
) 
for /l %%n in (1,1,6) do (
    if !score[%%n]! == 60 (
        echo winner: %%n
        set /a totalscore[%%n]=!totalscore[%%n]! + 1
        set winner=1
    )
) 

echo.
echo Previous Results
for /l %%n in (1,1,6) do (
    echo %%n: !totalscore[%%n]!
) 

if %winner%==1 GOTO END
timeout /t 0 /nobreak > NUL

GOTO LOOP

:END
echo.
pause

GOTO START

EDIT I think its a probability quirk, as Horse 6 has a chance to finish after 10 turns, where all other horses physically can't. This adds up for each horse, reducing the horses below it's chances (i.e horse 1 will only win if the other's all under perform).

Thanks for the responses :)

Foi útil?

Solução

The issue comes down to probability!

If we simplfy the game down to 6 moves:

  • Horse 1 will finish in 6 moves, however horse 6 has 5 attempts to beat it at 1/6 chance each try.

  • The odds of horse 6 NOT finishing = (5/6)^5 = 0.40 Therefore the odds of horse 6 finishing in 5 moves or less is 0.6

If we do this for each of the horses, poor horse 1 never stood a chance!

Outras dicas

Sintax in calcs is incorrect. Please change to

rem Generate a number in range [1-%%n]
set /a num=!random! * %%n / 32767 + 1

rem if horse number is <= random then move horse 
if !num! GEQ %%n set /a score[%%n]=!score[%%n]! + %%n

%random% return a number between 0 and 32767

%random% variable returns a supposedly evenly distributed number between 0 and 32767, so the right way to get a number between 1 and n with the same distribution is:

set /a num=!random! * %%n / 32768 + 1

... that may also be obtained this way:

set /a "num=!random! * %%n >> 16 + 1"

If you use the remainder (modulus) of %random% by the number n this way:

set /a num=!random! %% %%n + 1

... then you get a completely different and unknown distribution that may be biased towards certain value.

The generation of an evenly distributed random number is not easy, so you should make good use of the method used to generate %random% variable and not change its original distribution.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top