小编BRP*_*ock的帖子

我该如何处理AI线程与主游戏循环之间的通信?

我正在研究基于回合制的Java战略游戏(在Android框架中).按照Beginning Android Games中的结构,我有一个渲染线程和一个UI线程.渲染线程重复更新世界状态,然后重绘世界.当用户与屏幕交互时,GUI将动作发送到世界(命令模式).现在我正在添加AI玩家,这是我的计划:

每个AI播放器都有一个在单独的线程上运行的AI.

当世界更新AI时,它会检查是否有待处理的操作.如果是这样,它会执行它.然后它要求AI播放器进行下一步操作.

AI播放器将向AI线程发送动作请求,然后返回.

最终,人工智能将提出一个动作,并将其发布回世界,它将在下次更新时看到它.

两个问题:

1)这个设计看起来好听吗?

2)如何处理与AI线程的通信?如果我有AI线程调用world.queueAction(action),看起来它会工作,但是如果渲染线程调用ai.chooseAction(world)将在渲染线程上运行选择操作,这不是我想要的.

java multithreading android artificial-intelligence

5
推荐指数
1
解决办法
1015
查看次数

使用动态内容刷新wxGrid

这似乎并不像我希望的那么简单:

使用wxWidgets(2.8稳定系列),我有一个wxGrid(不是子类),自定义"数据适配器"作为wxGridTableBase派生类.

wxGrid* grid = new wxGrid (this, ID_TABLE);
grid->SetTable (new TableAdapter (foo, bar, baz));
grid->EnableEditing (false);
sizer->Add(grid, wxSizerFlags (1).Expand());
Run Code Online (Sandbox Code Playgroud)

我找不到的"简单"的东西是在底层数据模型发生变化时刷新网格的一种方法.简单地调用wxWindow :: Update(pGrid->Update())显然不足以让网格调用底层的wxGridTableBase实现?

wxGrid* const grid = (wxGrid* const) FindWindow (ID_TABLE);
if (NULL != grid) {
     grid->Update ();
     grid->AutoSizeColumns ();
}
Run Code Online (Sandbox Code Playgroud)

特别是,此网格充当列表,并且将通过相同或(可能)另一个进程异步添加和删除行 - 它是可由多个联网系统中的任何一个更新的共享数据列表.网格/列表本身实际上是只读的; 其他控件用于添加和删除项,每行都有一个布尔类型属性,也可以切换.

似乎新行未添加到视图中,删除行将导致wx绘图代码中的间歇性SEGV.

由于动态/异步更新机制,我希望避免不断删除并重新添加网格到窗口,因为我确信会导致各种闪烁和肮脏......所以,我会摔倒如果我绝对必须这样做,那就回去尝试一些类似暴力的东西,但我更倾向于避免它.

不幸的是,尽管被标记为"稳定版本",但wxGrid文档似乎主要由Yet to be written标签组成.

更新: 我开始怀疑这是容器布局问题.在绘制网格时,网格的底部(最后一行)实际上可以围绕wxFrame窗口部分的wxStaticBox框架以及框架状态行的一部分重叠.添加和删​​除行似乎不会强制重新布局容器; 我正在尝试打电话Layout等.理想情况下,这应该是一个滚动区域,但wxGrid 仍应在其包含的Sizer中"约束".

布局实际上包含一个静态框,其中包含一个垂直框,第一个元素是一个水平的按钮框,然后是网格,如下所示:

    --[ Static Box ]------------------------
   |                                        |
   | [Button] [Button] [Button]             |
   |                                        |
   |  ----------------------------------- …
Run Code Online (Sandbox Code Playgroud)

c++ wxwidgets

5
推荐指数
1
解决办法
7397
查看次数

是否有更优雅的方法来检测大型SQL表中的更改而不更改它?

假设你有一个相当大的(对于"大"的本地定义),但相对稳定的表.

现在,我想要对整个表的某些内容(任何类型)进行校验和.

天真的方法可能是遍历整个表,采用每行上每列连接的校验和(比方说,MD5),然后将它们连接起来并取其MD5sum.

从客户端开始,可以通过逐步将列的值附加到MD5求和例程中来逐步优化,逐步改变该值.

原因是,在将来的某个时刻,我们希望重新连接到数据库,并确保没有其他用户可能改变了表:包括INSERT,UPDATE和DELETE.

有没有更好的方法来确定特定表是否发生了任何更改?还是更有效/更快的方式?

更新/澄清:

  • 我们无法/允许对表本身进行任何更改(例如,添加"last-updated-at"列或触发器等)

(这适用于Postgres,如果它有帮助的话.我宁愿避免戳交易期刊或类似的东西,但如果有办法这样做,我不反对这个想法.)

sql postgresql checksum

3
推荐指数
1
解决办法
9056
查看次数

SBCL:继续在COMPILE期间重新启动?(真的是:HANDLER-CASE缺席)

swig用于包装C++库时,我一直试图绕过一个errorun eqlconstant 的编译时被重新定义...在这种情况下,是一个equal但不是eql字符串的文字.

奇怪的是,在SLIME中我能够简单地调用CONTINUE重启并绕过这个特定的错误.然而,当我尝试用把它包起来handler-case,并通过完成构建它compile-fileslime-compile-file或通过buildapp,将CONTINUE重启似乎缺少.(format t "Restarts: ~{~% • ~A~% ~:*~S~}" (compute-restarts))赞同.只是为了偏执,我试过:

   (continue)
   (invoke-restart 'continue)
   (invoke-restart (find-restart 'cl::continue))
Run Code Online (Sandbox Code Playgroud)

还有一些变化.

(unless (continue) (warn "Can't continue")) 奇怪的是,也没有警告我,但编译也没有完成文件.

由于我想要转换为关键字参数的一些更可怕的C++多态的情况,我继续使用swig生成的代码的复制和编辑版本,但我很好奇为什么重启将不存在以及我是否可以做了一些事情(可能是一些难以定位的动态设置)会绕过它.

编辑:为了避免它有用,一个变量已经:

(handler-case
  (compile-file "path/to/swig-made-this-mess")
  ;; contains (defconstant foo "string")

  #+sbcl
  (SB-EXT:DEFCONSTANT-UNEQL (condition)
    (let ((name (SB-EXT:DEFCONSTANT-UNEQL-NAME condition))
          (before (SB-EXT:DEFCONSTANT-UNEQL-OLD-VALUE condition))
          (after (SB-EXT:DEFCONSTANT-UNEQL-NEW-VALUE condition)))
      (if (equal before after)
          (progn
            (warn "Redefining …
Run Code Online (Sandbox Code Playgroud)

error-handling sbcl common-lisp

3
推荐指数
1
解决办法
117
查看次数

使用不同参数列表"重载"CLOS多方法

我试图在Common Lisp中对多方法进行"重载调用".这是案例的简化纲要:

(defclass foo ()
  ((slotty :accessor slotty :initarg :slotty)))

(defclass bar ()
  ((slotty :accessor slotty :initarg :slotty)))

(defparameter *foo* (make-instance 'foo :slotty "defnoodle"))
(defparameter *bar* (make-instance 'bar :slotty "Chocolate"))

(defmethod contrived ((f foo) (b bar))
  (format t "i pity the foo ~A, who has a bar ~A ~%" (slotty f) (slotty b)))

(contrived *foo* *bar*)
Run Code Online (Sandbox Code Playgroud)

输出: i pity the foo defnoodle, who has a bar Chocolate

但是一旦我尝试定义下一个方法:

 (defmethod contrived ((f foo))
    (format  t "i just pity the foo ~A …
Run Code Online (Sandbox Code Playgroud)

lisp common-lisp clos

3
推荐指数
1
解决办法
334
查看次数