2014-04-22 1 views
-2

저는 최근에 체스를 재생하는 인공 지능을 작성했습니다. AI는 클라이언트 서버에 각각 연결된 두 개의 개별 인스턴스를 실행하도록 설계되었습니다. 서버는 각 AI에 대해 실행 함수를 차례로 호출합니다. 내가하려고하는 것은 다른 인공 지능이 움직이는 동안 숙고하는 코드를 작성하는 것이다. 그러나, 나는 문제점을 가로 질러왔다. 쉽게 말했다 문제를 설명 할 수 있도록 내가 코드를 보여 드리겠습니다 :"이전에 초기화 된 변수에 할당되지 않은 로컬 변수 'ponderThread'를 사용했습니다.

public override bool run() 
{ 
    PonderSearch ponderSearch = new PonderSearch(); 
    Thread ponderThread; 
    AIMove bestMove = null; 
    int Depth = 0; 

    // Print the board 
    if (moves.Length < 2) 
    { 
     theBoard.Print(); 
    } 

    if (!FirstTurn) 
    { 
     AIMove lastMove = new AIMove(AI.moves[0]); 
     Depth = ponderSearch.Depth; 

     foreach (MoveTable result in ponderSearch.TheTable) 
     { 
      if (result.TheMove == lastMove) 
      { 
       bestMove = result.TheResult.Move; 
      } 
     } 

     // End thread 
     ponderThread.Abort(); 
     ponderThread.Join(); 
    } 

    // Looks through information about the players 
    for (int p = 0; p < players.Length; p++) 
    { 
     Console.Write(players[p].getPlayerName()); 

     // if playerID is 0, you're white, if its 1, you're black 
     if (players[p].getId() == playerID()) 
     { 
      Console.Write(" (ME)"); 
     } 

     Console.WriteLine(" time remaining: " + players[p].getTime()); 
    } 

    AIMove otherPMove = new AIMove(); 
    AIPiece pieceMoved = new AIPiece(); 

    // if there has been a move, print the most recent move 
    if (moves.Length > 0) 
    { 
     // Update the board state with previous move 
     theBoard = theBoard.Update(); 
     pieceMoved = theBoard.GetPiece((short)moves[0].getToRank(), 
      (short)moves[0].getToFile()); 
     otherPMove = new AIMove(moves[0], pieceMoved); 

     if (lastMoves.Count >= 8) 
     { 
      lastMoves.RemoveAt(7); 
     } 

     lastMoves.Insert(0, otherPMove); 
    } 

    // Generate move 
    Search theSearch = new Search(lastMoves); 

    if (!FirstTurn) 
    { 
     theSearch.Update(Depth, bestMove); 
    } 

    AIMove theMove = theSearch.Minimax(theBoard, (short)playerID()); 

    // Update last 8 moves 
    if (lastMoves.Count >= 8) 
    { 
     lastMoves.RemoveAt(7); 
    } 

    lastMoves.Insert(0, theMove); 

    if (theMove != null) 
    { 
     Console.WriteLine("Move Chosen:"); 
     theMove.Print(); 
     theBoard = theBoard.Move(theMove, (short)playerID()); 
    } 
    else 
    { 
     Console.WriteLine("No move available"); 
    } 

    theBoard.Print(); 

    // Begin pondering 
    ponderSearch = new PonderSearch(lastMoves, (short)playerID(), theBoard, theMove); 
    ponderThread = new Thread(new ThreadStart(ponderSearch.Ponder)); 
    ponderThread.Start(); 
    FirstTurn = false; 
    return true; 
} 

어쨌든, 작성된를, 컴파일러는 내 스레드가 초기화되지 않은 말을 여러 오류가 발생하지만 점은 함수가 여러 번 실행하는 것입니다 가장 최근 호출에서 현재 호출의 시작 부분에서 시작된 스레드를 종료합니다.

내가 할 수있는 방법이 있습니까?

감사합니다,

편집 : 내가 오류는 다음과 같습니다

Error 4 Use of unassigned local variable 'ponderThread' C:\Users\...\AI.CS 52 13 csclient 
+3

질문의 제목 자체는 의미가 없습니다! –

+1

.NET에서 Task Parallelism Library를 사용하면 멀티 스레드 프로그래밍을 수행하는 것이 좋습니다. 다른 스레드에서 실행되는 "작업"을 상호 작용하기가 훨씬 쉬운 "작업"으로 추상화 할 수 있기 때문입니다. 작업을 기다리는 계속 작업은 훨씬 간단합니다. –

+0

@AppDeveloper : 내 제목을 이해하기가 어려울 경우 죄송합니다. 그게 내 문제를 설명하기 위해 생각할 수있는 최선의 방법이었습니다 – Woody1193

답변

0

이 스레딩 함께 할 수 없다. 간단한 범위 지정 문제입니다. 메소드 내에서 선언 된 모든 지역 변수는 일반적으로 스택에 저장되고 메소드가 존재할 때 정리됩니다.

따라서 run() 메소드가 종료 된 후에 ponderThread은 가비지 수집됩니다. 따라서 다음 번에 메소드를 입력하면 FirstTurn 멤버 변수가 true로 설정되고 ponderThread 변수는 로컬 변수이므로 초기화되지 않습니다.

빠른 수정은 ponderThread 변수를 클래스 변수 (C#의 멤버 변수)로 변경하는 것입니다.

그러나 두 스레드간에 상태를 공유하려고하면 스레드 동기화 문제가 발생합니다.

추가 정보를 얻기 전에 스레드에 대해 좀 더 읽어 보시기 바랍니다.

+0

감사! 왜 스레드를 메서드 변수 대신 클래스 변수로 만들지는 않았지만 내 문제가 해결 된 이유는 모르겠습니다. – Woody1193

관련 문제