2016-04-12 14 views
0

günceller. Bir sınıf örneğinde bir yöntemi çağırmanın başka bir sınıf örneğini güncelleştirdiği bir soruna rastlıyorum. Kazanma gelen oyuncu engellemeye çalışması bilgisayar davranışını oluşturmak çalışıyorumYakut - Güncellenmesi Bir Sınıf Instance İstemeden ben Ruby basit tic tac toe program oluşturmak için çalışıyorum Başka Sınıf örneği ve

class Game 
    attr_accessor :turn_count, :all_positions_occupied, :winner, :rows, :columns, :diagonals 

    def initialize 
     @turn_count = 0 

     @all_positions_occupied = {1 => "*", 2 => "*", 3 => "*", 
            4 => "*", 5 => "*", 6 => "*", 
            7 => "*", 8 => "*", 9 => "*"} 

     @winner = nil 

     @rows = { 1 => [1, 2, 3], 2 => [4, 5, 6], 3 => [7, 8, 9] } 

     @columns = { 1 => [1, 4, 7], 2 => [2, 5, 8], 3 => [3, 6, 9] } 

     @diagonals = { 1 => [1, 5, 9], 2 => [3, 5, 7] } 
    end 

    def refresh_line(line, item, symbol) 
     line.each do |key, value| 
      if value.include?(item) 
       value[(value.index(item))] = symbol 
      end 
     end 
    end 

    def occupy_selected(selection, symbol) 
     @all_positions_occupied[selection] = symbol 

     # Refresh rows, columns, and diagonals 

     refresh_line(@rows, selection, symbol) 
     refresh_line(@columns, selection, symbol) 
     refresh_line(@diagonals, selection, symbol) 
    end 

    def copy_onto_virtual_board(virtual_game) 
     virtual_game.all_positions_occupied = @all_positions_occupied.clone 
     virtual_game.rows = @rows.clone 
     virtual_game.columns = @columns.clone 
     virtual_game.diagonals = @diagonals.clone 
    end 
end 

: Sorun aşağıda gösterilmiştir benim Oyun sınıfındadır. Ana kodumda bir "real_game" ve bir "virtual_game" oluşturmak istiyorum. Gitme bilgisayarın dönüş olduğunda, ben aşağıdaki yöntemi çalıştırmak istiyorum: Ben real_game.copy_onto_virtual_board(virtual_game) kullanmak kez Bununla

def block_win(virtual_game) 
     # Copy Real Board Onto Virtual Board Using 'copy_onto_virtual_board(virtual_game)' 
     # Create Array of Available Positions 
     # Cycle Through Array of Available -> 'available_positions.each do |position|' 
      # Occupy 'position' on the Virtual Board with 'X' using 'occupy_selected(position, 'X') 
      # If 'virtual_game.check_for_winner' is not nil 
       # Have Computer Occupy that Position with 'O', effectively blocking 'X' from taking that position and winning 
      # Else 
       # Re-Copy Real Board Onto the Virtual Board Using 'copy_onto_virtual_board(virtual_game)' 
    end 

real_game ve virtual_game ben virtual_game üzerinde occupy_selected(position, "X") her kullandığınızda o, o uygular böylece bir şekilde bağlantılı hale real_game için de aynı yöntem. Bu, real_game'den ayrı bir virtual_game'e sahip olmanın tüm amacını yener. copy_onto_virtual_board yöntemini kullanmadığım sürece, iki oyun ayrı ayrı davranır.

neden Buna yol açabilecek olarak herhangi bir fikir? Bunun kıvrımlı bir açıklama olduğunu biliyorum, bu yüzden ihtiyacınız olabilecek diğer bilgileri bana bildirin.

Yardımlarınız için teşekkürler.

GÜNCELLEME ----------- aşağıda engineersmnky, Güncellenmiş tarafından aşağıdaki yöntemi verilen yanıta göre

:

def copy_onto_virtual_board(virtual_game) 
     virtual_game.all_positions_occupied = @all_positions_occupied.clone 
     virtual_game.rows = @rows.keys.zip(@rows.values.map(&:clone)).to_h 
     virtual_game.columns = @columns.keys.zip(@columns.values.map(&:clone)).to_h 
     virtual_game.diagonals = @diagonals.keys.zip(@diagonals.values.map(&:clone)).to_h 
end 

block_win yöntem dönmek üzere ayarlandı varsa blokaj pozisyonu. Aksi takdirde, kullanılabilir_pozisyon dizisine göre rastgele bir pozisyon döndürür.

+3

Sorunuzla ilgili bölümü kesin olarak belirlemek için kodu daraltın. Onu okumaktan hoşlanmıyorum. – sawa

+0

Sorunun, Hashes ('@ satırları ',' @ 'sütunları', 'köşegenler') içerisindeki dizilerin hala referanslarını koruduğu sığ kopyalamadan kaynaklandığını düşünüyorum. . "Virtual_game" etkilememelidir "real_game" iç 'Array' anlam değişiklikleri klonlamak bu to_h' – engineersmnky

+0

: belki' @ rows.keys.zip (klon) @ rows.values.map (&) gibi bir şey denemek @engineersmnky, bu mükemmel çalıştı! Teşekkür ederim. Şimdi sadece bu kodun aslında ne yaptığını anlamaya ihtiyacım var. Bunun için belgelere bakacağım. –

cevap

0

Bunun nedeni size derin kopyalama karmaları olmaması. Bu, #clone kullanarak, aynı dizileri işaret eden anahtarlarla yeni bir karma oluşturduğunuz anlamına gelir.

Sen Marshal.load(Marshal.dump(hash)) yerine hash.clone ile yakut derin kopyalarını yapabilirsiniz. Bu, başvurulan tüm nesnelerin tam kopyalarını oluşturur.

Ama bunu tavsiye ve gerekmez böylece tasarımını gözden geçirmenizi öneriyoruz etmemelidir.

İlgili konular