Tictactoe and choice


#1

I was trying to code the classic tictactoe in ruby.
Now it only plays itself doing random moves until someone wins, and
there
are still some bugs.

But the thing that really I don’t understand is another,

With this line every time I pick the next move:

x, y = (0…(board.length)).to_a.choice, (0…
(board.length)).to_a.choice

But I get always the same game!!:

step 0 we have:
[[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]

step 1 we have:
[[nil, nil, “O”], [nil, nil, nil], [nil, nil, “X”]]

step 2 we have:
[[nil, “O”, “O”], [“X”, nil, nil], [nil, nil, “X”]]
sorry 2, 2 already set
sorry 0, 2 already set

step 3 we have:
[[nil, “O”, “X”], [“X”, nil, nil], [“O”, “X”, “X”]]
player X has won
[[nil, “O”, “X”], [“X”, nil, “X”], [“O”, “X”, “X”]]

It looks like there’s nothing really random here, am I missing
something maybe??
The full source code

http://pastie.textmate.org/private/ivw3qswnf6rbppyd78m0qq

Thanks a lot for any hint


#2

Hello andrea,

(board.length)).to_a.choice

But I get always the same game!!:

[snip]

You should add a call to srand before the call to random_play. It
will seed the random number generator so that you don’t get the
same sequence of random numbers every time you run your program.


#3

Thanks a lot now it’s working pretty nicely

http://pastie.textmate.org/private/0qfnvswccjfqhbe73ql7q

There are still a few things that I don’t like though.
For example here
def reset_board(len = 3)
board = []
free = []
(0…(len)).each { board << [nil] * len }

setting all the free cells

for i in (0…(len))
for j in (0…(len))
free << [i, j]
end
end
[board, free]
end

I generate the empty board and the free places, can I generate free
with
only one block?

Same thing in the check procedure, I’m first trying to call chkline
for every line,
creating the array of truth values and then calling truth.any?
It’s a little be boring, I would like to do

and [ check x | x <- gen_lines board]

(as I would do in Haskell more or less)

def check(board)
chk = lambda { |vals| vals.any? and vals.uniq.length == 1 }
truth = []
chk_line = lambda { |b| b.each { |line| truth << (chk.call line) }}
chk_line.call gen_lines board
chk_line.call gen_lines board.transpose

truth is automatically updated in the two calls

truth.any?
end

def gen_lines(board)
diag = []
to_check = []
(0…(board.length)).each { |i| diag << board[i][i]; to_check <<
board[i] }
to_check << diag
to_check
end


#4

On 8 Gen, 10:09, Jesús Gabriel y Galán removed_email_address@domain.invalid
wrote:

end

end

Not in a single loop but I’d do:

0.upto(len-1) {|i| 0.upto(len-1) {|j| free << [i,j]}}

[board, free]
end

Jesus.

Thanks a lot, with classes is much much better and cleaner
http://pastie.textmate.org/private/hompwzt9vu5oz7dkwryrg

Now I have to implement the decision engine and that’s it, I could be
satisfied.

I wanted to try to use callcc for the decision tree (along with a
normal backtrack stack),
could it be a good idea?


#5

On Thu, Jan 8, 2009 at 9:49 AM, andrea removed_email_address@domain.invalid wrote:

There are still a few things that I don’t like though.
For example here
def reset_board(len = 3)

board = []

(0…(len)).each { board << [nil] * len }

board = Array.new(len) {[nil]*len}

free = []

setting all the free cells

for i in (0…(len))

for j in (0…(len))

free << [i, j]

end

end

Not in a single loop but I’d do:

0.upto(len-1) {|i| 0.upto(len-1) {|j| free << [i,j]}}

[board, free]
end

Jesus.