// Action Selection Thread, runs minimax on the current State to get the best Action. Also keeps a history and updates it based on the successes and fails of the AI protected static void selectAction(object arg) { Thread.Sleep(1000); // Sleep to prevent race conditions on game load PaddleController __this = (PaddleController)arg; ActionStateMap.GameObjectState localState = new ActionStateMap.GameObjectState(Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, 0.0f); int maxHistory = 1000; int historyIndex = 0; Tuple <ActionStateMap.GameAction, ActionStateMap.ActionState>[] previousActions = new Tuple <ActionStateMap.GameAction, ActionStateMap.ActionState> [maxHistory]; while (!(__this.closeThreads.WaitOne(0))) { if (__this.currStateLock.WaitOne(1000)) { localState.copy(__this.currState); __this.currStateLock.ReleaseMutex(); ActionStateMap.GameObjectState currState = localState; Tuple <double, ActionStateMap.GameAction, ActionStateMap.ActionState> nextAction = __this.minimax(currState, 3); if (nextAction.Item2.getTag() != __this.currAction.getTag()) { __this.setNextAction(nextAction.Item2); } // Store history and adjust weight on success and fail previousActions[historyIndex] = Tuple.Create(nextAction.Item2, nextAction.Item3); historyIndex++; if (historyIndex >= maxHistory) { bool success = __this.successEvent.WaitOne(0); bool fail = __this.failEvent.WaitOne(0); __this.successEvent.Reset(); __this.failEvent.Reset(); historyIndex = 0; for (int i = 0; i < maxHistory; i++) { if (success) { previousActions[i].Item2.updateActionProbabilities(previousActions[i].Item1, 1.0); } if (fail) { previousActions[i].Item2.updateActionProbabilities(previousActions[i].Item1, -1.0); } } } } } }
// Update thread for the Player StateMap. Records movements of the Player protected static void updatePlayerMap(object arg) { Thread.Sleep(1000); // Sleep to prevent race conditions on game load PaddleController __this = (PaddleController)arg; ActionStateMap.GameObjectState localState = new ActionStateMap.GameObjectState(Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, 0.0f); ActionStateMap.GameObjectState prevState = new ActionStateMap.GameObjectState(Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, 0.0f); while (!(__this.closeThreads.WaitOne(0))) { if (__this.currStateLock.WaitOne(1000)) { localState.copy(__this.currState); __this.currStateLock.ReleaseMutex(); __this.playerStateMap.recordAction(prevState, localState); prevState.copy(localState); Thread.Sleep(100); } } }