TicTacToe invalid move method issue - ruby

Below is my take for the TicTacToe game. So far it works, but it's not perfect. I'm having an issue with one of the methods - Game#invalid_move_check? after the game asked you "where to:"once choose the new destination , the game change the symbol like if it was a new turn .in fact not , suppose to keep the same player symbol until next turn.
P.S the code probably need some refactoring. I'm in a learning phase.
class Game
def initialize(symbol)
#board = Array.new(3){Array.new(3)}
# [0,1,2]
# [3,4,5]
# [6,7,8]
#symbol = ["X", "O"]
end
WINNING_COMBO = [
# Horizontal wins:
[0, 1, 2], [3, 4, 5], [6, 7, 8],
# Vertical wins:
[0, 3, 6], [1, 4, 7], [2, 5, 8],
# Diagonal wins:
[0, 4, 8], [2, 4, 6]
]
def create_players
# create both players
#names = []
print "Please enter the name of the first player: "
#player_1 =gets.chomp
#names << #player_1
print "Please enter the name of the second player: "
#player_2 = gets.chomp
#names << #player_2
puts "\n"
puts"welcome #{#player_1.upcase} and #{#player_2.upcase}"
puts"------------------------------------------------"
puts"\n"
puts "Randomizing who'll start..."
puts"\n"
# assign player by calling the player_assigment function that will determine who will start first
player_assigment
puts"\n"
end
def player_assigment
# merge the names array and symbol array
# with the zip method and return a nested array with player and symbol.
#choice = #names.zip(#symbol)
# iterate over the choice nested array and
# print out each player and their assigned symbol
#choice.each do |player, symbol|
puts "#{player.upcase} will use #{symbol}"
end
end
def current
#current = #names.first
#current
end
def switch_turn
#current = #names.last
#current
end
def first_turn
current
puts "#{#current.upcase} turn"
#marker = #symbol.first
make_move(#marker)
end
def next_turn
switch_turn
puts "#{#current.upcase} turn"
#marker = #symbol.last
make_move(#marker)
end
def check_win?(first_arr, second_arr)
WINNING_COMBO.select do |item|
if
item == first_arr
puts"#{#player_1} won!!"
elsif
item == second_arr
puts "#{#player_2} won!!"
end
end
end
def mapping(move, marker)
case move
when 0
arr_index = 0
index = 0
invalid_move_check?(arr_index,index)
#board[0][0] = marker
when 1
arr_index = 0
index = 1
invalid_move_check?(arr_index,index)
#board[0][1] = marker
when 2
arr_index = 0
index = 2
invalid_move_check?(arr_index,index)
#board[0][2] = marker
when 3
arr_index = 1
index = 0
invalid_move_check?(arr_index,index)
#board[1][0] = marker
when 4
arr_index = 1
index = 1
invalid_move_check?(arr_index,index)
#board[1][1] = marker
when 5
arr_index = 1
index = 2
invalid_move_check?(arr_index,index)
#board[1][2] = marker
when 6
arr_index = 2
index = 0
invalid_move_check?(arr_index,index)
#board[2][0] = marker
when 7
arr_index = 2
index = 1
invalid_move_check?(arr_index,index)
#board[2][1] = marker
when 8
arr_index = 2
index = 2
invalid_move_check?(arr_index,index)
#board[2][2] = marker
end
end
def invalid
puts"move invalid"
end
def invalid_move_check?(arr_index, index)
array = #board
if array[arr_index][index] == "X" ||
array[arr_index][index] == "O"
invalid
puts "Where to :"
#move = gets.chomp.to_i
mapping(#move,#marker)
end
end
def make_move(marker)
# after each turn the make_move method will called to place move on the board
puts "Where to :"
#move = gets.chomp.to_i
mapping(#move,#marker)
print_board
end
# display board in a matrix format
def print_board
#board.each_slice(1) { |a| p a }
puts"\n"
end
def instructions
puts "Instructions :Enter your first move by entering a number 1-9"
puts "corresponding to the grid on the bottom and press enter"
puts"\n"
puts "0 | 1 | 2 ",
"----------",
"3 | 4 | 5 ",
"----------",
"6 | 7 | 8 "
print"\n"
end
def self.start(symbol)
# start a new game
new_game =Game.new(symbol)
# create players
new_game.create_players
new_game.instructions
new_game.print_board
# Checking wining combo for matching patter if none
while new_game.check_win?(#move_first, #move_second) do
new_game.first_turn
# the player switch turn
new_game.next_turn
end
end
loop do
puts"------------------------------------------------"
puts" Welcome to tictactoe ".upcase
puts"------------------------------------------------"
print"\n"
Game.start(#symbol)
end
end

This should do the trick:
#will return true or false to check validity of move
def invalid_move_check?(arr_index, index)
array = #board
if array[arr_index][index] == "X" ||
array[arr_index][index] == "O"
invalid
puts "Where to :"
#move = gets.chomp.to_i
mapping(#move,#marker)
return true
end
return false
end
def mapping(move, marker)
case move
...
when 0
arr_index = 0
index = 0
unless invalid_move_check?(arr_index,index) #change all cases
#board[0][0] = marker #to have the assignment of board
#only if the move is valid
end
...
end
end
The reason of your bug is that the assignment happens even if the move is invalid.
This is just a band-aid solution to your current problem, as for refactoring ,there are things that can be done to optimize your code and make it better :) But you still have to fix first your 'ending'. Refactoring your own code would be a very good practice. I wish you a joyful ruby journey
!

After scratching the previous code and rethink the code i 've come up with this solution , not elegant as i will want it to be but it works .i move the symbol assignment in the if/else block code and therefore when a move is invalid next move will use the symbol of the current player
def mapping(move, symbol)
case move
when 0
if #board[0][0]=="X" || #board[0][0] == "O"
invalid
make_move
else
#board[0][0] = symbol
track_move(#move)
print_board
end
...
end
end

Related

Building tic tac toe game through scratch stuck while checking winning

I can play the game. Switch the player all working fine but not getting result who won the game.
def initialize_board
#count = 9
#player = PLAYER_ONE #current_player
#board = Array.new(3){ Array.new(3, " ") }
end
def play
inputs = get_inputs
return false if !inputs
update_board(inputs)
print_board
end
def switch_player
if(#player == PLAYER_ONE)
#player = PLAYER_TWO
else
#player = PLAYER_ONE
end
end
def game_over?
# #count = #count - 1
# #count <= 0
if check_winner
puts "#{#player} won "
end
end
def check_winner
WIN_COMBINATIONS.find do |indices|
binding.pry
values = #board.values_at(*indices)
values.all?('X') || values.all?('O')
end
end
Here I am getting indices [0,1,2] in all cases while debugging.
The main reason why you're not getting the winner is because your 'values = #board.values_at(*indices)' statement returns an array of arrays. And values.all?('X') || values.all?('O') checks not an 'X' or 'O' pattern but an array object. So you need to flatten an array first.
values.flatten!
Stefan already answered similar question , but his board was one-dimensional because of %w expression, you can read about it here

Trying to cull a set but the set keeps disappearing

I'm trying to program the AI for a Mastermind game in ruby using Donal Knuth's 5 guess algorithm. The game consists of a codemaker, who uses 8 different colored pegs to create a set of 4, and a codebreaker, who guesses at the code and receives feedback (a red square for a peg which is both the right color and in the right spot, and a white square for a peg which is the right color but in the wrong spot).
I've created a set for all possible codes. My goal is to compare feedback from the guess to feedback from all codes in the set, then delete the ones that don't match. It seems to delete the entire set though.
class ComputerPlayer < Player
def initialize(game)
super(game)
#all_possible_codes = create_codes
#turn = 1
end
def get_code
Array.new(4){rand(1..6)}
end
def get_guess
puts #all_possible_codes.length
if #turn == 0
#turn += 1
cull_set([1, 1, 2, 2])
#all_possible_codes.delete("1122")
return [1, 1, 2, 2]
else
random_sample = #all_possible_codes.to_a.sample.split('').map{|str| str.to_i}
#all_possible_codes.delete(random_sample.join(''))
cull_set(random_sample)
random_sample
end
end
def cull_set(guess)
feedback = #game.feedback_on_guess(guess)
puts feedback
#all_possible_codes.delete_if { |str| #game.feedback_on_guess(str.split.map{|num| num.to_i}) != feedback }
end
def create_codes
set = Set.new
(1..8).each do |i|
(1..8).each do |j|
(1..8).each do |k|
(1..8).each do |l|
set << [i, j, k, l].join('')
end
end
end
end
set
end
end
#this is the feedback_on_guess method used by the above class
def feedback_on_guess(code_guess)
code_duplicate = #code
feedback = []
code_duplicate.map.with_index do |entry, i|
if entry == code_guess[i]
feedback.push('r')
code_guess[i] = -1
-2
else
entry
end
end.each do |entry|
found_index = code_guess.find_index(entry)
if found_index
feedback.push('g')
code_guess[found_index] = -1
end
end
puts feedback
feedback
end
Try
copy = something.dup
because after just
copy = something
copy and something are pointing to the same object. You can confirm this by checking the object_id of the object referenced by the variable. If it is the same, then it is the same object.
When you dup an object, you will cretae a copy. Depending on what you want to dup you might need to implement/override the logic to create a copy. For built in Classes like String, Hash and so on it will work out of the box.
Be aware that nested constructs (eq. Hash containing other Hashes) are not duplicated.
h1 = {"a" => {"b" => 2}}
h2 = h1.dup
puts h1.object_id # 70199597610060
puts h2.object_id # 70199597627020
puts h1["a"].object_id # 70199597610080
puts h2["a"].object_id # 70199597610080

Wrote TicTacToe in ruby and the computer is not playing nice

Basically the computer_make_move method is simple. I just want it to pick an open position and take it. It's meant to be dumb. It's not meant to play skillfully (yet).
Problem is that for some off reason. Every time I make a move, the computer makes a random number of moves.. Sometimes 1, other times 3 or 6. Just strange behavior. I don't understand why.
Note any reference to a method not seen here is in the gameart.rb file and it all art eg. you_win is just art, no logic at all.
Here is all the code:
class TicTacToe
require 'colorize'
require_relative 'lib/gameart.rb'
attr_reader :home_screen_ninja_art
WINS = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 5, 9], [3, 5, 7], [1, 4, 7], [2, 5, 8], [3, 6, 9]]
##scoreboard = {player: 0, computer: 0, tie: 0}
def initialize name, mark
#name, #gameover, #game_memory, #winner = name, false, ['_','_','_','_','_','_','_','_','_'], ''
mark == 'X' ? (#player, #computer = 'X', 'O') : (#player, #computer = 'O', 'X')
end
def menu i
return render_board if i == 99
return about if i == 100
return how_to_play if i == 200
return scoreboard if i == 300
return goodbye if i == 400
end
def action move
return menu(move) if move > 10
current_caller = caller[0] =~ /computer_make_move/ ? #computer : #player
i = move-1
if #game_memory[i] == '_'
render_board(i, current_caller)
else
try_again_art
end
end
def computer_make_move
action(current_board_positions[2].sample+1) # just pick any random open space for now
end
def render_board input=nil, caller=nil
if #gameover == false && !input.nil?
#game_memory[input] = caller
verify_game_state
end
if #gameover == true
game_over_art
case
when #winner == 'TIE' then you_tied
when #winner == #player then you_win
when #winner != #player then you_lose
end
end
board = #game_memory.map {|ps| ps == 'X' ? ps.colorize(:blue) : ps.colorize(:green) }.map {|ps| ps.gsub(/_/, " ")}
show_board board
end
def current_board_positions
x_positions, o_positions = [], []
#game_memory.select.with_index do |v,i|
x_positions << i+1 if v == 'X'
o_positions << i+1 if v == 'O'
end
open_positions = (1..9).to_a - (x_positions + o_positions)
[x_positions, o_positions, open_positions]
end
def verify_game_state
x, o, open = current_board_positions
find_winner = ->side { WINS.map {|win| side.combination(3).to_a.map {|set| set == win }.include? true } }
case
when (find_winner.(x).include? true)
#gameover=true
#winner='X'
when (find_winner.(o).include? true)
#gameover=true
#winner='O'
when !#game_memory.include?('_')
#gameover=true
#winner='TIE'
else
computer_make_move
end
end
end
This is how I initialize the game:
# Start a game
def start_new_game name, mark
#f = TicTacToe.new(name, mark)
puts #f.action 99
loop do
if #f.instance_variable_get :#gameover
puts 'Ready to play again?'.colorize(:white).on_red
print ' y|yes '.colorize(:green)
print ' n|no '.colorize(:red)
valid = false
until valid
startover = gets.chomp
valid = true if startover =~ /y|n|yes|no/i
end
if startover =~ /y|yes/i
start_new_game name, mark
else
#f.goodbye
end
else
print "* "
puts "Make your move #{name}:".colorize(:white).on_red
end
move = gets.chomp
puts #f.action move.to_i
end
end
valid = false
until valid
TicTacToe.home_screen_ninja_art
puts 'What is your name?'.colorize(:white).on_red
name = gets.chomp
valid = true if name.length > 1
end
valid = false
until valid
TicTacToe.home_screen_ninja_art
puts 'Pick your mark?'.colorize(:white).on_red
print ' X '.colorize(:blue)
print ' O '.colorize(:green)
puts ''
mark = gets.chomp.upcase
if mark =~ /X|O/i
valid = true
end
end
start_new_game name, mark
In method verify_game_state that calls after each render_board there is no case when person make move. It has only someone winners or tie, OR computer_make_move, so no noly computer should make a move.
So every time when it's not the end of the game, computer make a move, until it is, as i can see.

A very specific Conway's Game of Life (Ruby beginner)

Looking for feedback on obvious logic errors on this, not optimizing. I keep getting weird tick counts on the end game message (ex: 1 tick turns into 11 ticks)
The largest error I can spot while running the code is on the 2nd tick, a very large amount of alive cells appear. I am too new to this to understand why, but it seems like the #alive_cells is not resetting back to 0 after each check.
Here is my entire code, its large but it should be child's play to anyone with experience.
class CellGame
def initialize
puts "How big do you want this game?"
#size = gets.chomp.to_i
#cell_grid = Array.new(#size) { Array.new(#size) }
#grid_storage = Array.new(#size) { Array.new(#size) }
#tick_count = 0
fill_grid_with_random_cells
end
def fill_grid_with_random_cells
#cell_grid.each do |row|
row.map! do |cell|
roll = rand(10)
if roll > 9
"•"
else
" "
end
end
end
check_cells_for_future_state
end
def check_for_any_alive_cells
#cell_grid.each do |row|
if row.include?("•")
check_cells_for_future_state
break
else
end_game_print_result
end
end
end
def check_cells_for_future_state
#cell_grid.each_with_index do |row, row_index|
row.each_with_index do |cell, cell_index|
#live_neighbors = 0
add_row_shift = (row_index + 1)
if add_row_shift == #size
add_row_shift = 0
end
add_cell_shift = (cell_index + 1)
if add_cell_shift == #size
add_cell_shift = 0
end
def does_this_include_alive(cell)
if cell.include?("•")
#live_neighbors +=1
end
end
top_left_cell = #cell_grid[(row_index - 1)][(cell_index - 1)]
does_this_include_alive(top_left_cell)
top_cell = #cell_grid[(row_index - 1)][(cell_index)]
does_this_include_alive(top_cell)
top_right_cell = #cell_grid[(row_index - 1)][(add_cell_shift)]
does_this_include_alive(top_right_cell)
right_cell = #cell_grid[(row_index)][(add_cell_shift)]
does_this_include_alive(right_cell)
bottom_right_cell = #cell_grid[(add_row_shift)][(add_cell_shift)]
does_this_include_alive(bottom_right_cell)
bottom_cell = #cell_grid[(add_row_shift)][(cell_index)]
does_this_include_alive(bottom_cell)
bottom_left_cell = #cell_grid[(add_row_shift)][(cell_index - 1)]
does_this_include_alive(bottom_left_cell)
left_cell = #cell_grid[(row_index)][(cell_index - 1)]
does_this_include_alive(left_cell)
if #live_neighbors == 2 || #live_neighbors == 3
#grid_storage[row_index][cell_index] = "•"
else
#grid_storage[row_index][cell_index] = " "
end
end
end
update_cell_grid
end
def update_cell_grid
#cell_grid = #grid_storage
print_cell_grid_and_counter
end
def print_cell_grid_and_counter
system"clear"
#cell_grid.each do |row|
row.each do |cell|
print cell + " "
end
print "\n"
end
#tick_count += 1
print "\n"
print "Days passed: #{#tick_count}"
sleep(0.25)
check_for_any_alive_cells
end
def end_game_print_result
print "#{#tick_count} ticks were played, end of game."
exit
end
end
I couldn't see where your code went wrong. It does have a recursive call which can easily cause strange behavior. Here is what I came up with:
class CellGame
def initialize(size)
#size = size; #archive = []
#grid = Array.new(size) { Array.new(size) { rand(3).zero? } }
end
def lives_on?(row, col)
neighborhood = (-1..1).map { |r| (-1..1).map { |c| #grid[row + r] && #grid[row + r][col + c] } }
its_alive = neighborhood[1].delete_at(1)
neighbors = neighborhood.flatten.count(true)
neighbors == 3 || neighbors == 2 && its_alive
end
def next_gen
(0...#size).map { |row| (0...#size).map { |col| lives_on?(row, col) } }
end
def play
tick = 0; incr = 1
loop do
#archive.include?(#grid) ? incr = 0 : #archive << #grid
sleep(0.5); system "clear"; #grid = next_gen
puts "tick - #{tick += incr}"
puts #grid.map { |row| row.map { |cell| cell ? '*' : ' ' }.inspect }
end
end
end
cg = CellGame.new 10
cg.play
The tick count stops but the program keeps running through the oscillator at the end.
I wanted to revisit this and confidently say I have figured it out! Here is my new solution - still super beginner focused. Hope it helps someone out.
class Game
# Uses constants for values that won't change
LIVE = "🦄"
DEAD = " "
WIDTH = 68
HEIGHT = 34
def initialize
# Sets our grid to a new empty grid (set by method below)
#grid = empty_grid
# Randomly fills our grid with live cells
#grid.each do |row|
# Map will construct our new array, we use map! to edit the #grid
row.map! do |cell|
if rand(10) == 1
LIVE # Place a live cell
else
DEAD # Place a dead cell
end
end
end
# Single line implimentation
# #grid.each {|row|row.map! {|cell|rand(10) == 1 ? LIVE : DEAD}}
loop_cells #start the cycle
end
def empty_grid
Array.new(HEIGHT) do
# Creates an array with HEIGHT number of empty arrays
Array.new(WIDTH) do
# Fills each array with a dead cell WIDTH number of times
DEAD
end
end
# Single line implimentation
# Array.new(HEIGHT){ Array.new(WIDTH) { DEAD } }
end
def print_grid # Prints our grid to the terminal
system "clear" # Clears the terminal window
# Joins cells in each row with an empty space
rows = #grid.map do |row|
row.join(" ")
end
# Print rows joined by a new line
print rows.join("\n")
# Single line implimentation
# print #grid.map{|row| row.join(" ")}.join("\n")
end
def loop_cells
print_grid # Start by printing the current grid
new_grid = empty_grid # Set an empty grid (this will be the next life cycle)
# Loop through every cell in every row
#grid.each_with_index do |row, row_index|
row.each_with_index do |cell, cell_index|
# Find the cells friends
friends = find_friends(row_index, cell_index)
# Apply life or death rules
if cell == LIVE
state = friends.size.between?(2,3)
else
state = friends.size == 3
end
# Set cell in new_grid for the next cycle
new_grid[row_index][cell_index] = state ? LIVE : DEAD
end
end
# Replace grid and start over
#grid = new_grid
start_over
end
def find_friends(row_index, cell_index)
# Ruby can reach backwards through arrays and start over at the end - but it cannot reach forwards. If we're going off the grid, start over at 0
row_fix = true if (row_index + 1) == HEIGHT
cell_fix = true if (cell_index + 1) == WIDTH
# You'll see below I will use 0 if one of these values is truthy when checking cells to the upper right, right, lower right, lower, and lower left.
# Check each neighbor, use 0 if we're reaching too far
friends = [
#grid[(row_index - 1)][(cell_index - 1)],
#grid[(row_index - 1)][(cell_index)],
#grid[(row_index - 1)][(cell_fix ? 0 : cell_index + 1)],
#grid[(row_index)][(cell_fix ? 0 : cell_index + 1)],
#grid[(row_fix ? 0 : row_index + 1)][(cell_fix ? 0 : cell_index + 1)],
#grid[(row_fix ? 0 : row_index + 1)][(cell_index)],
#grid[(row_fix ? 0 : row_index + 1)][(cell_index - 1)],
#grid[(row_index)][(cell_index - 1)]
]
# Maps live neighbors into an array, removes nil values
friends.map{|x| x if x == LIVE}.compact
end
def start_over
sleep 0.1
loop_cells
end
end
# Start game when file is run
Game.new

Passing arguments to functions in ruby using variables

Following the tutorial Zed A. Shaw, I'm writing a soccer game. My code so far is as follows:
$team_a_players = ["Basar", "Mehmet", "Abdullah", "Alpaslan", "Salih", "Recep", "Ibrahim", "Orhan", "Hakki", "Yakup", "Serdar"]
$team_a_substitutes = ["Hasan", "Turgay", "Umit"]
$team_b_players = ["Habib", "Erkan", "Sahin", "Cemal", "Ahmet", "Fikret", "Yucel", "Pergel", "Ali", "Sabri", "Yilmaz"]
$team_b_substitutes = ["Abdulkadir", "Gokhan", "Mustafa"]
$yellow = []
$red = []
$reasons = ["corner", "direct attack", "free kick", "side attack", "speed kick"]
$team_a_attack = 90.0
$team_a_defense = 80.0
$team_b_attack = 70.0
$team_b_defense = 60.0
$team_a_goals = 0
$team_b_goals = 0
def prompt()
print "> "
end
def dice()
if rand(2) == 0
round_team_a()
else
round_team_b()
end
end
def fauls()
if rand(0) > 0.95 and rand(10) % 2 == 0
faul_player = $team_a_players[rand(11)]
if $yellow.include?(faul_player)
$red.push(faul_player)
$team_a_players.delete("faulplayer")
puts "#{faul_player} of Team A gets a red card in #{$i}. minute!"
puts "Who would you like to substitute in place of #{faul_player}?"
list_subs_a()
prompt()
substitute = STDIN.gets.chomp()
$team_a_players.push("substitute")
$yellow.delete(faul_player)
else
$yellow.push(faul_player)
puts "#{faul_player} of Team A gets a yellow card in #{$i}. minute!"
end
elsif rand(0) > 0.95 and rand(10) % 2 == 1
faul_player = $team_b_players[rand(11)]
if $yellow.include?(faul_player)
$red.push(faul_player)
$team_b_players.delete("faulplayer")
puts "#{faul_player} of Team B gets a red card in #{$i}. minute!"
puts "Who would you like to substitute in place of #{faul_player}?"
list_subs_b()
prompt()
substitute = STDIN.gets.chomp()
$team_b_players.push("substitute")
$yellow.delete(faul_player)
else
$yellow.push(faul_player)
puts "#{faul_player} of Team B gets a yellow card in #{$i}. minute!"
end
else
faul_player = nil
end
end
def list_subs_a()
$team_a_substitutes.each {|p| puts p}
end
def list_subs_b()
$team_b_substitutes.each {|p| puts p}
end
def list_yellow()
$yellow.each {|p| puts p}
end
def list_red()
$red.each {|p| puts p}
end
def round_team_a()
score = $team_a_attack / $team_b_defense * rand(0)
if score > 1
goal = 1
$team_a_goals += 1
reason = $reasons[rand(5)]
puts "Team A scored #{goal} goal through a #{reason} in #{$i}. minute!"
else
goal = 0
end
end
def round_team_b()
score = $team_b_attack / $team_a_defense * rand(0)
if score > 1
goal = 1
$team_b_goals += 1
reason = $reasons[rand(5)]
puts "Team B scored #{goal} goal through a #{reason} in #{$i}. minute!"
else
goal = 0
end
end
def match()
$i = 0
until $i > 59 do
dice()
fauls()
$i += 1
end
puts "Team A scored a total of #{$team_a_goals} goals and Team B scored a total of #{$team_b_goals} goals."
if $team_a_goals > $team_b_goals
puts "Team A won against Team B by #{$team_a_goals}:#{$team_b_goals}!"
elsif $team_b_goals > $team_a_goals
puts "Team B won against Team A by #{$team_b_goals}:#{$team_b_goals}!"
else
puts "It's a tie!"
end
if $yellow.length > 0
puts "Players shown a yellow card are:"
list_yellow()
else
puts "No yellow cards in the end of the game"
end
if $red.length > 0
puts "Players shown a red card are:"
list_red()
else
puts "No red cards in the end of the game"
end
end
match()
From here, I would like to do the following:
Replace the arrays $yellow and $red with hashes so that I can also report minutes and teams of yellow- and red-cards.
Replace the arrays starting with the name $team_ with hashes so that I can add individualized attack- and defense-powers to players so that substitutions mean sth. but before the code gets any more complex, I have to solve sth. This looks similar to this question concerning php.
Define the functions list, round and faul in a way that can be used common to a_players and b_players . I tried doing team_#{team}_players instead of team_a_players etc, but cannot achieve it.
What I seek is a guide to that problem, not a solution, so that I can fix this myself. A link or long explanation in clear words is very much more welcome than a fixed code. And please note that the tutorial has not mentioned classes yet, so this is not an option yet.
The basic idea you haven't seemed to grasp is passing arguments to functions.
Assume we have two global variables and we wish to perform identical operations on them - say multiply elements of arrays by 2.
You write:
$a = [1,2,3]
$b = [2,3,4]
def multiply_a
result = []
for element in $a do
result << element * 2
end
result
end
def multiply_b
result = []
for element in $b do
result << element * 2
end
result
end
But this code is very bad. First of all, you should note that in Ruby $a is a special variable - a global variable. You should never need to use them - writing code containing them means that there is something wrong with it. So how to fix it?
The basic idea is to pass an argument to a function, instead of hard coding the variable, the function operates on. So you can transform the code as follows:
a = [1, 2, 3]
b = [2, 3, 4]
def multiply(argument)
result = []
for element in argument do
result << element * 2
end
result
end
# and then call
multiply(a) # instead of multiply_a
multiply(b) # instead of multiply_b
This is the way you should fix your code.

Resources