2016-11-08 6 views
0

私はPythonに関する非常に基本的な知識を持つ物理学者ですが、私はこの問題の簡単な解決策を探していますが、円。私は "The Game of Life"というプログラムのために私自身の演出を書いています(WikiPage)。規則は簡単です:LIfeのゲーム:条件で反復処理中にnumpyで配列値を変更する

ゲームは2次元グリッド上にあるいわゆるセルで構成されています。これらの細胞は周期的に進化する。死んで生きている細胞の初期のパターンは、第1世代です。第2世代は、いくつかの単純なルールをすべてのセルに同時に適用することから進化しています。ルールは以下のとおりです。彼らは十分な会社(隣接2個の未満の細胞)は、隣接する4個の以上のセルがある場合

細胞は人口過剰で死ぬを持っていけない場合

細胞が死にます。

(正確に)3つのセルが隣接していると、死んだセルが生まれ変わります。

これは割り当ての一部ですが、私はスプーンフィードソリューションを探していません。 numpyと配列を使用する必要があります。

私のアプローチは、ランダムな1と0の初期フィードで配列boardを生成することでした。次に、関数内で、新しい値を格納してからそれを戻すboardより大きい1行と1列の別の配列を作成します。私は反復する(配列上で反復するためにpythonicでないことを知っているので、ijの要素に対しては提案や代替案が公開されている)、サブ配列nBlock[i-1:i+1,j-1:j+1]の合計(np.sum)を作る。合計が4よりも大きいか4より小さい場合、要素nBlock[np.array([i,j])]はゼロ(セルが死ぬ)になり、それ以外の場合は1(セルが生き残り、または生まれ変わります)になります。

問題は、これは機能しません。コードは次のとおりです。

import numpy as np 
import matplotlib.pyplot as plot 
import time as t 
%matplotlib inline 

def printBoard(board): 
    im = plot.imshow(board, cmap='Greys', interpolation='none') 
    plot.show() 
    plot.close() 

def initializeBoard(): 
    board = np.random.randint(2, size=(100, 100)) 
    return board 

board = initializeBoard() 
printBoard(board) 

def checkAlive(): 
    if 1 not in board: 
     print("All cells are dead! Life is over!") 
     return 0 
    else: 
     return board 

def calculateNeighbours(board): 
    nBlock = np.zeros((102, 102)) 
    nBlock[1:101, 1:101] = board 

    for i in range(1, 100): 
     for j in range(1, 100): 
      checksum = np.sum(nBlock[i-1:i+2, j-1:j+2]) 

      nBlock[:,0] = 0 
      nBlock[0,:] = 0 

      if checksum == 4: 
       nBlock[np.array([i,j])] = 1 
      elif checksum > 4 or checksum < 4: 
       nBlock[np.array([i,j])] = 0 

    return nBlock 

def play(board): 
    for i in range(1, 10): 
     neighbours = calculateNeighbours(board) 

     board = neighbours[1:101, 1:101] 

     board = checkAlive() 

     printBoard(board) 

play(board) 

アレイboardは変更されません。同じboardを返します。

私が気づいた別の奇妙なことは、私のforループの条件を削除すると、配列が正常に変更されてしまうことです。例えば、

for i in range(0, 100): 
    for j in range(0, 100): 
     board[np.array([i,j])] = 1 

は私ので、私は私の配列内のデータを操作できるようにされていないif...else条件について何かがある1に変更されたすべての要素を持つ行列を与えます。

任意およびすべてのヘルプは高く評価され:)

+0

[convolution](https://jakevdp.github.io/blog/2013/08/07/conways-game-of-life/)を使用して最近傍を数えたとお考えですか? – wflynny

+0

@ Alex.S私はなぜ、 'return'ブロックをforループに入れるべきかわかりません。ループするたびに配列を返しませんか?とにかく、うまくいきませんでした:( – shashtheash

+0

@wflynny私は畳み込みについて読むことができるリソースを教えていただけますか?scipyのドキュメントはここであまり役に立ちません.../ – shashtheash

答えて

0

エラー

あなたの主要なエラーがcheckAliveのためのあなたのインタフェースロジックです。ルーチンにはパラメータはありません。ライブセルを見つけたら、シンビオントボードを返します。プレイは、パラメータのボードにすぐに割り当てられます。

ボードで遊びはローカル変数である:これはあなたが初期化さグローバルボードを変更しない変更します。対照的に、のcheckAliveはローカル変数を持たないので、グローバル変数ボードは決して変更されません。

ソリューション:checkAliveはボードを変更しません

ので、それを返しません。代わりに、単純なブール値を返します。 の再生はこれをチェックし、必要に応じてプログラムを終了することができます。また

あなたの細胞の健康のアルゴリズムは、点のカップルで間違っています。論理を歩き、修復する。最も顕著なのは、セルを生存させるために値4を使用することです。これは大規模に間違っています。 2隣人は、セルをその現在の状態のままにする。 3人の隣人が細胞を生きる。それ以外の番号はそれを殺します。

現在のロジックには、セル自体がカウントに含まれます。これは、3人の友人の生きた細胞と4人の死んだ細胞を区別するものではありません。その結果、いくつかの細胞を間違って作り出し、生きている細胞を殺しています。

+0

ありがとうございました!ロジックの私の目立った欠陥と組み合わせて、私のコードを完全に台無しにしました:P 私はこれらのことを両方とも修正しました。私のロジックにはさらに重要な欠陥があるのが分かりました。要素ごとに反復処理をしているので、コードを1行ずつ変更することになります。その結果、白黒の代替線が得られます。私は元の値を格納するために別の配列を使う必要があります。 – shashtheash

関連する問題