在我正在编写的一个使用UIKit的快速游戏中,人类玩家将与UIKit UIButtons、GUI元素交互以采取行动。
在比赛中,玩家将与AI球员比赛。
但事情是这样的:人类玩家按下按钮和交互,而人工智能玩家没有。
给出一个简单的UIViewController;
class SampleViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func buyBtnPressed(_ sender: UIButton) {
print ("pressed")
}
}所以我要确定的是,AI玩家自己是如何在当前视图控制器的上下文中采取行动和处理转弯的呢?
我相信最好的方法是,应该有一个循环,等待所有的球员已经完成各自的回合。
但是这个循环到哪里去了呢?在视图里装了吗?
如果是这样的话,它会不会消耗掉内存,或者可能导致(如果不小心的话)一个没完没了的循环?
考虑到UIViewController元素是用于人类交互的,我发现很难确定AI玩家如何在给定的上下文中采取行动。
我并不是说AI应该是动画按钮或与屏幕交互,我的意思是,我有一个UIViewController,它有一个视图确实加载;什么是实现人工智能转弯的策略,这应该是在一个“游戏循环”在视图加载或这可以通过另一种方式实现吗?
我的问题是:考虑到UIViewController的上下文,我如何对AI玩家轮流进行的处理进行编码,这是否可以通过循环或其他策略来实现?
非常感谢
编辑:现在添加了代码
我已经写了一个使用Swift游乐场的转基管理器,两个例子--一个使用UIViewController,另一个是循环。
现在代码如下;
import Foundation
import GameplayKit
class Player {
var name: String
public private(set) var isAI: Bool = false
public private(set) var turnOrder: Int = 0
init(name: String, isAI: Bool?) {
self.name = name
if let hasAI = isAI {
self.isAI = hasAI
}
}
func setTurnOrderIndex(number: Int) {
self.turnOrder = number
}
}
let p1 = Player.init(name: "Bob", isAI: false)
let p2 = Player.init(name: "Alex", isAI: true)
protocol TurnOrderManagerDelegate: NSObjectProtocol {
func turnOrderWasSet()
}
protocol TurnDelegate: class {
func turnIsCompleted()
}
class Turn: NSObject {
weak var player: Player?
weak var delegate: TurnDelegate?
public private(set) var completed: Bool = false {
didSet {
delegate?.turnIsCompleted()
}
}
init(player:Player, delegate: TurnDelegate) {
self.player = player
self.delegate = delegate
}
func setAsComplete() {
self.completed = true
}
}
class TurnOrderManager: NSObject, TurnOrderManagerDelegate, TurnDelegate {
static var instance = TurnOrderManager()
public private(set) var turnOrderIndex: Int = 0
public private(set) var turnOrder: [Turn] = [Turn]() {
didSet {
self.turnOrderWasSet()
}
}
var playerOnTurn: Player? {
let turnObj = self.turnOrder[turnOrderIndex]
return (turnObj.player)
}
var allTurnsCompleted: Bool {
let filtered = turnOrder.filter { (turnObj:Turn) -> Bool in
return (turnObj.completed)
}.count
return (filtered == turnOrder.count)
}
func setTurnOrder(players:[Player]) {
if (self.turnOrder.count == 0) {
for playerObj in players {
let turnObj = Turn.init(player: playerObj, delegate: self)
self.turnOrder.append(turnObj)
}
}
}
func turnOrderWasSet() {
for (index, turnObj) in self.turnOrder.enumerated() {
turnObj.player?.setTurnOrderIndex(number: index)
}
}
func next() {
if (turnOrderIndex < (self.turnOrder.count - 1)) {
turnOrderIndex += 1
}
else {
turnOrderIndex = 0
}
}
internal func turnIsCompleted() {
print (" - turnIsCompleted")
TurnOrderManager.instance.next()
}
}
class GameModel {
var turnOrderManager: TurnOrderManager
init() {
self.turnOrderManager = TurnOrderManager.instance
self.turnOrderManager.setTurnOrder(players:[p1,p2])
}
// other game model stuff [...]
}
class Phase1State : GKState {
var gameModel: GameModel!
init(gameModel:GameModel) {
super.init()
self.gameModel = gameModel
}
override func isValidNextState(_ stateClass: AnyClass) -> Bool
{
return false
}
override func didEnter(from previousState: GKState?) {
}
override func willExit(to nextState: GKState) {
}
// MARK: - Action
func buy() {
let index = self.gameModel.turnOrderManager.turnOrderIndex
let turn = self.gameModel.turnOrderManager.turnOrder[index]
turn.setAsComplete()
}
}
class SomeViewController: UIViewController
{
var gameModel: GameModel?
weak var gamePhase: Phase1State?
var isPhaseComplete: Bool {
return self.gameModel?.turnOrderManager.allTurnsCompleted ?? false
}
override func viewDidLoad() {
super.viewDidLoad()
self.gameModel = GameModel.init()
self.gamePhase = Phase1State.init(gameModel: self.gameModel!)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func buyButtonPressed() {
self.gamePhase?.buy()
self.finishTurn()
}
func finishTurn() {
guard let turnIndex = self.gameModel?.turnOrderManager.turnOrderIndex else {
return
}
guard let turn = self.gameModel?.turnOrderManager.turnOrder[turnIndex] else {
return
}
turn.setAsComplete()
if (self.isPhaseComplete)
{
print ("All turns are completed")
}
else {
//self.gameModel?.turnOrderManager.next()
self.gamePhase?.buy()
guard let playerOnTurn = self.gameModel?.turnOrderManager.playerOnTurn else {
print ("No player is on turn")
return
}
print ("\(playerOnTurn.name) is on turn")
if (playerOnTurn.isAI)
{
self.gamePhase?.buy()
self.finishTurn()
}
}
}
}
// EXAMPLE 1 -- first attempt ...
let vc = SomeViewController()
vc.viewDidLoad()
vc.buyButtonPressed()
// EXAMPLE 2 -- another attempt ....
let gameModel: GameModel = GameModel.init()
let gamePhase = Phase1State.init(gameModel: gameModel)
// player then takes an action
while (gameModel.turnOrderManager.allTurnsCompleted == false)
{
let turnIndex = gameModel.turnOrderManager.turnOrderIndex
let turnObj = gameModel.turnOrderManager.turnOrder[turnIndex]
guard let playerOnTurn = turnObj.player else {
break
}
print ("Player \(playerOnTurn.name) is on turn")
gamePhase.buy()
}
print ("All turns are completed, advance to next phase")问题是;
在finishTurn上,只有当它依赖于索引中的第一个玩家是人为玩家时,它才能工作。如果没有,我不知道如何让它启动购买行动。
在第二个例子中,我使用了一个循环;但是我担心使用循环可能会永远循环。
因此,我的查询是明确的,我如何确保我的视图控制器将启动行动为AI玩家,当他们不按下按钮和循环通过每个玩家,并执行各自的回合。
非常感谢
进一步编辑:
我不知道在我的while (gameModel.turnOrderManager.allTurnsCompleted == false) ()中是否应该有viewDidLoad循环来充当游戏循环。
发布于 2017-06-26 13:02:32
没有必要为此专门使用雪碧套件。SpriteKit将更多地与UI的制作方式有关,而不是游戏的逻辑。
不过,我建议您看看GameplayKit。这是一个包含大量内置游戏逻辑工具的框架。特别是,您需要类似于GKDecisionTree的东西。有一些关于它的WWDC视频。GameplayKit可以与SpriteKit、UIKit、SSceneKit或您决定使用的任何其他游戏引擎一起使用。
另外,你要问的问题是关于游戏开发的一个非常普遍的问题。让计算机“决定”做某事是一个相当复杂的问题。
我还建议快速观看这是来自AI和游戏的视频和该频道的其他视频。
它会给你一个如何处理你的问题的想法。
WWDC 2015和2016的第609和608次会议都很好:D
关于更新人工智能的问题。
你的人工智能应该是事件驱动的。你有“转身”和“玩家”的概念。游戏中有一个点,它变成了“玩家”的“转弯”。(即使在比赛刚开始的时候,也是第一名球员或者是第二名球员。
此时有两种可能性。玩家要么是人工智能,要么是人。
一旦发生这种情况,就应该有某种类型的触发器(比如函数调用或其他什么),告诉玩家该回合已经开始。
如果那个玩家是AI,那么你需要开始某种计算(可能需要一个内置的延迟,以使它切合实际),以便它决定做什么。
发布于 2017-06-26 12:41:36
听着,我不知道你在做什么样的游戏,买你应该学SpriteKit,特别是SKActions。有了它,你就可以轻松地控制游戏中的事件流。
话虽如此,你的人工智能实现得如何?根据您的代码,我将从以下内容开始:
class AI {
enum Decision {
case doSomething
case doAnotherThing
case dontDoAnything
}
public func decide() -> Decision {
// Decide which action the AI will take...
return .doSomething // This return is just a example!
}
public func act(on : Decision) {
// Do whatever the AI needs based on a decision...
}
}然后,在您的ViewController中:
class SampleViewController: UIViewController {
var ai = AI()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func buyBtnPressed(_ sender: UIButton) {
print ("pressed")
ai.act(on: ai.decide())
}
}我希望这能帮上忙!
https://stackoverflow.com/questions/44759546
复制相似问题