【问题标题】:How to design an interactive Sudoku grid in Racket?如何在 Racket 中设计交互式数独网格?
【发布时间】:2022-01-08 21:53:18
【问题描述】:

我现在正在尝试在 Drracket 中创建数独游戏。我已经设法设计了随机生成数独并检查用户答案是否正确的函数。但是现在我在设计交互式 Suduko 网格时遇到了一些麻烦。
我想创建一个数独网格,允许用户单击一个单元格来“激活”它(这也意味着用户不能在错误的地方填写数字)并用数字(1-9)填充它或删除数字。同时通过“查答功能”可以检测出每个小区的情况。


我用来表示数独数列表的数据类型

; the ElementState of the test right solution *TME means test element

(define TRS (list TME-44 TME-34 TME-24 TME-14 TME04 TME14 TME24 TME34 TME44
                  TME-43 TME-33 TME-23 TME-13 TME03 TME13 TME23 TME33 TME43
                  TME-42 TME-32 TME-22 TME-12 TME02 TME12 TME22 TME32 TME42
                  TME-41 TME-31 TME-21 TME-11 TME01 TME11 TME21 TME31 TME41
                  TME-40 TME-30 TME-20 TME-10 TME00 TME10 TME20 TME30 TME40
                  TME-4-1 TME-3-1 TME-2-1 TME-1-1 TME0-1 TME1-1 TME2-1 TME3-1 TME4-1
                  TME-4-2 TME-3-2 TME-2-2 TME-1-2 TME0-2 TME1-2 TME2-2 TME3-2 TME4-2
                  TME-4-3 TME-3-3 TME-2-3 TME-1-3 TME0-3 TME1-3 TME2-3 TME3-3 TME4-3
                  TME-4-4 TME-3-4 TME-2-4 TME-1-4 TME0-4 TME1-4 TME2-4 TME3-4 TME4-4))

SudokuNumber 结构在哪里

(define-struct SudokuNumber [number position])
*For the position, I created a coordinate system by defining the position of 
the center cell is (0,0), so every cell has a unique position from (-4.-4) to (4,4)

我现在的想法是当用户改变一个cell的情况时,SudokuNumber的List对应元素的情况也随之改变。所以“检查答案功能”可以通过检查列表来工作。

所以现在我唯一的问题是如何设计交互式数独网格。

【问题讨论】:

    标签: scheme lisp racket interactive sudoku


    【解决方案1】:

    如果您正在做一个 GUI,您可以使用 text-field%canvas%。无论您选择哪种方式,我都建议您创建一个小部件,以便您可以在任何地方重用它(并使测试更容易)。要创建一个新的小部件,请执行以下操作:

    (module sudoku
      mzscheme
      
      (provide (all-defined))
      
      (require  (lib "mred.ss" "mred"))
      
      (define my-sudoku%
        (class canvas%
          (init-field parent)
          (init-field callback)
    
          (super-new (parent parent)(min-width 500)(horiz-margin 2)(vert-margin 2)
                     (paint-callback (lambda (cnv dc)(PaintCallback cnv dc)))
                     (style '(control-border vscroll hscroll)))
    ...
    

    文本字段接受回调,因此您可以在该点验证/拒绝新输入...使用水平和垂直面板创建网格。

    如果你使用 canvas% 的方式(我个人最喜欢),你必须实现所有东西,但是你有更多的灵活性。在这种情况下,Paint 事件每次都必须重新绘制整个数独表,on click 事件将更改活动单元格(如果适用),on-char 事件将验证按下的键并在适当时更新值。例如,这里有一个使用 canvas% 制作的小部件示例,它允许您使用鼠标进行绘制。修改它来实现数独应该很容易。

    (define canva-pintable%
        (class canvas%
          (init-field parent) ; parent of this control
          (init-field color)  ; color to use for painting
    
          (super-new (parent parent)(min-width 400)(min-height 400)(horiz-margin 2)(vert-margin 2)
                     ; In this example we don't need a redraw function. For sudoku you should implement it, so that the window is redraw each time you move/resize the window.
                     (paint-callback (lambda (cnv dc)(void)))
                     (style '(control-border vscroll hscroll)))
          
          (send (send this get-dc) set-pen color 1 'solid)
          
          ;receives an mouse-event%
          (define/override (on-event event)
            (cond ((send event dragging?) (send (send this get-dc) draw-point (send event get-x) (send event get-y)))
            )
            )
          
          (define/override (on-char event)
            (send (send this get-dc) clear)
            )
          )
        ) 
    
    (define myWindow (new frame% (label "Draw on me!")))
    (define myCanva (new canva-pintable% (parent myWindow)(color "black")))
    (send myWindow show #t)
    

    【讨论】:

      猜你喜欢
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      • 2023-03-04
      • 1970-01-01
      • 2021-05-29
      相关资源
      最近更新 更多