Symbol tricks

Trying to write one function that will find a
full row or column in a 2D array (for tic-tac-toe).
Like this:


$grid =
[[’ ‘,’ ‘,‘O’],
[‘X’,‘X’,‘X’],
[‘O’,’ ‘,’ ']]

def doAxis (outr,inr)
outerLoop:
[0,1,2].each do |:"#{outr}"|
[0,1,2].each do |:"#{inr}"|
if ($grid[row][col] != ‘X’)
next outerLoop # is this supported?
end
end
puts “Got 3 in a row!”
return true
end
false
end

doAxis ‘row’, ‘col’ # want to find full rows
doAxis ‘col’, ‘row’ # want to find full columns

Is this possible? So far Ruby doesn’t seem to like it.
What are the limits to how you can use this construction?

:"#{foo}"

I don’t think you can use a symbol in a parameter list ever.

-j

(grid+grid.transpose).map {|x,y,z| x==‘X’ && x==y && y==z}

As long as you don’t want diagonals

YAD wrote:

Trying to write one function that will find a
full row or column in a 2D array (for tic-tac-toe).

I’m making an assumption here, that you want to find a winning pattern.


#! /usr/bin/ruby

grid =
[
[‘X’,’ ‘,‘O’],
[’ ‘,‘O’,’ ‘],
[‘O’,’ ',‘X’]
]

def test_rows(array)
array.each do |row|
return row.first if (row.first != ’ ’ && row.uniq.size == 1)
end
return false
end

def test_diagonals(array)
c = array[1][1]
if(c != ’ ')
return c if((c == array[0][2] && c == array[2][0])
|| (c == array[0][0] && c == array[2][2]))
end
return false
end

def find_winner(array)
w = test_rows(array)
|| test_rows(array.transpose)
|| test_diagonals(array)
puts “found winning row for player “#{w}”” if w
end

find_winner(grid)

Output: found winning row for player “O”

Johannes Held wrote:

Paul L. schrieb:

I’m making an assumption here, that you want to find a winning pattern.
snipped the code
Output: found winning row for player “O”
That’s an elegant solution without “black magic”.

Thanks, you are very kind. I personally think my diagonal finder is
rather
like squeezing blood from a stone. I suspect someone will think of a
more
elegant solution that remains human-readable.

Thanks again. :slight_smile:

Jason N. wrote:

I don’t think you can use a symbol in a parameter list ever.
Thanks. I just wanted to make sure.

(grid+grid.transpose)
Is this correct Ruby? If so, is it documented online somewhere?
You’re not really adding the arrays, are you?

Also, transpose sounds like the simplest solution.

Paul L. wrote:

I’m making an assumption here, that you want to find a winning pattern.
I want to calculate several things (at different times), including
whether a player has two in a row, and whether a player has two blank
squares that will win the game (two pairs in a row that require
different squares to be completed).
Since that’s a total of six functions, I figured combining rows & cols
into one function would be the simplest way to reduce the total amount
of code.

def find_winner(array)
w = test_rows(array)
|| test_rows(array.transpose)
|| test_diagonals(array)

This looks like the simplest way to do it. The only concern I would
have with this solution is performance in searching a whole tree of
possible future grids.

Paul L. schrieb:

I’m making an assumption here, that you want to find a winning pattern.
snipped the code
Output: found winning row for player “O”
That’s an elegant solution without “black magic”.

YAD wrote:

Paul L. wrote:

I’m making an assumption here, that you want to find a winning pattern.
I want to calculate several things (at different times), including
whether a player has two in a row, and whether a player has two blank
squares that will win the game (two pairs in a row that require
different squares to be completed).
Since that’s a total of six functions, I figured combining rows & cols
into one function would be the simplest way to reduce the total amount
of code.

If speed is your primary goal (referring to later content in your post),
then minimizing the number of functions may not be so important.

def find_winner(array)
w = test_rows(array)
|| test_rows(array.transpose)
|| test_diagonals(array)

This looks like the simplest way to do it. The only concern I would
have with this solution is performance in searching a whole tree of
possible future grids.

Given the speed requirement, this might be a case where (at risk of
sounding
sacrilegious) you would test various approaches in Ruby until you came
up
with an obviously efficient method, then converted the algorithm into C
or
C++. In this case Ruby would serve as a quick prototyping tool (but a
comparatively slow execution tool).

As to “possible future grids”, if you factor out mirror reflections and
transpositions, there really aren’t that many unique board
configurations
in this game. Compare this to the Japanese game Go, which is still not
well-represented in a computer program.

YAD wrote:

Jason N. wrote:

(grid+grid.transpose)
Is this correct Ruby? If so, is it documented online somewhere?
You’re not really adding the arrays, are you?

Plus for arrays and strings is concatenation. I don’t like it either,
b/c array plus should be addition of corresponding elements, but that is
the way things are.

-j

Jason N. [email protected] writes:

YAD wrote:

Jason N. wrote:

(grid+grid.transpose)
Is this correct Ruby? If so, is it documented online somewhere?
You’re not really adding the arrays, are you?

Plus for arrays and strings is concatenation. I don’t like it either, b/c array plus should be addition of corresponding elements, but that is the way things are.

-j

require ‘matrix’
=> true
Vector[1,2,3] + Vector[4,5,6]
=> Vector[5, 7, 9]

Steve

Jason N. wrote:

YAD wrote:

Jason N. wrote:

(grid+grid.transpose)
Is this correct Ruby? If so, is it documented online somewhere?
You’re not really adding the arrays, are you?

Plus for arrays and strings is concatenation. I don’t like it either,
b/c array plus should be addition of corresponding elements, but that is
the way things are.

-j

No, Vectors should add elemets as they represent mesurable value.
Arrays are part of Set Thoery and as such + most obviously represents
the union of two sets.

This is niether correct nor intuitive:
[“red”,“orange”,yellow] + [“green”,“blue”,“purple”] =>
[“reggreen”,“orangeblue”,"yellowpurple] #incorrect!

Yes, that’s nice. Yet another module with different sematics to learn
and more type conversions to do. From learning Ruby, I’ve learned that
there is probably a package to do something. Too bad you also need
packages B and C and half a doze type conversion to do any interesting
data processing. And this comes from somebody who really wants to like
the language, but finds it frustratingly messy.

-j