ฟังก์ชั่นการเขียนโปรแกรมมีอะไรบ้างในการนำ Game of Life ของ Conway [ปิด]


12

ฉันเพิ่งนำมาใช้เพื่อความสนุกสนานGame of Life ของ Conwayใน Javascript (จริงๆแล้วกาแฟเป็นสิ่งเดียวกัน) เนื่องจากจาวาสคริปต์สามารถใช้เป็นภาษาที่ใช้งานได้ฉันจึงพยายามอยู่จนสุดช่วงความถี่ ฉันไม่พอใจกับผลลัพธ์ของฉัน ฉันเป็นโปรแกรมเมอร์ OO ที่ค่อนข้างดีและวิธีการแก้ปัญหาของฉันถูกตีเหมือนกันอายุเท่าเดิม คำถามยาว ๆ สั้น ๆ : รูปแบบการทำงาน (pseudocode) ของการทำคืออะไร?

นี่คือ Pseudocode สำหรับความพยายามของฉัน:

class Node
  update: (board) ->
    get number_of_alive_neighbors from board
    get this_is_alive from board
    if this_is_alive and number_of_alive_neighbors < 2 then die
    if this_is_alive and number_of_alive_neighbors > 3 then die
    if not this_is_alive and number_of_alive_neighbors == 3 then alive

class NodeLocations
  at: (x, y) -> return node value at x,y
  of: (node) -> return x,y of node

class Board
  getNeighbors: (node) -> 
   use node_locations to check 8 neighbors 
   around node and return count

nodes = for 1..100 new Node
state = new NodeState(nodes)
locations = new NodeLocations(nodes)
board = new Board(locations, state)

executeRound:
  state = clone state
  accumulated_changes = for n in nodes n.update(board)
  apply accumulated_changes to state
  board = new Board(locations, state)


@Oded ที่ซึมเศร้าเหนือหัวของฉัน ฉันรู้จักแนวคิดพื้นฐาน แต่เพิ่งจะแทบจะไม่ได้เลย
George Mauer

เหนือหัวของฉันด้วย ... ฉันเพิ่งโพสต์ไว้เพื่อเป็นตัวอย่างของต้นแบบของภาษาเฉพาะที่สามารถทำได้ เรียกมันว่าเป็นแรงบันดาลใจสำหรับพวกเราทุกคน :)
Oded

@GeorgeMauer "จริง ๆ แล้วกาแฟ แต่สิ่งเดียวกัน" นี่เป็นวันที่น่าเศร้า
Raynos

คำตอบ:


11

ความคิดสองสามอย่าง ฉันไม่ใช่ผู้เชี่ยวชาญใน FP แต่ ...

มันค่อนข้างชัดเจนว่าเราควรมีประเภทBoardที่แสดงถึงสถานะของเกม พื้นฐานของการดำเนินการควรเป็นevolveหน้าที่ของประเภทevolve :: Board -> Board; ความหมายมันผลิตจากการใช้กฎของเกมไปยังBoardBoard

เราควรนำไปใช้evolveอย่างไร A Boardน่าจะเป็นเมทริกซ์ nxm ของCells เราสามารถใช้ฟังก์ชั่นcellEvolveประเภทcellEvolve :: Cell -> [Cell] -> Cellที่กำหนด a CellและCells ข้างเคียงคำนวณCellสถานะในการทำซ้ำครั้งถัดไป

เราก็ควรที่จะใช้getCellNeighborsฟังก์ชั่นที่ดึงเพื่อนบ้านจากCell Boardฉันไม่แน่ใจทั้งหมดของลายเซ็นของวิธีนี้ ขึ้นอยู่กับว่าคุณจะใช้งานอย่างไรCellและBoardคุณอาจมีอินสแตนซ์getCellNeighbors :: Board -> CoordElem -> CoordElem -> [Cell]ซึ่งกำหนดให้บอร์ดและพิกัดสองอัน ( CoordElemเป็นประเภทที่ใช้ในการจัดทำดัชนีตำแหน่งใน a Board) จะให้รายการความยาวผันแปรของเพื่อนบ้าน (ไม่ใช่เซลล์ทั้งหมดในบอร์ด) จำนวนเพื่อนบ้านเท่ากันมีเพื่อนบ้าน 3 คนพรมแดน 5 และคนอื่น 8)

evolveสามารถนำมาใช้โดยการรวมcellEvolveและgetCellNeighborsสำหรับเซลล์ทั้งหมดในบอร์ดอีกครั้งการดำเนินการที่แน่นอนจะขึ้นอยู่กับวิธีการที่คุณใช้BoardและCellแต่มันควรจะเป็น "สำหรับทุกเซลล์ในบอร์ดปัจจุบันรับเพื่อนบ้านและใช้ในการคำนวณ เซลล์ที่สอดคล้องกันของบอร์ดใหม่ 'ซึ่งน่าจะเป็นไปได้ที่จะทำอย่างไรกับแอพพลิเคชั่นทั่วไปของฟังก์ชั่นเหล่านั้นทั่วทั้งกระดานโดยใช้ "map over function cell's board"

ความคิดอื่น ๆ:

  • คุณควรนำไปใช้จริงcellEvolveเพื่อใช้เป็นพารามิเตอร์ประเภทหนึ่งGameRulesซึ่งเข้ารหัสกฎของเกม - พูดรายการของสิ่งอันดับ(State,[(State,NumberOfNeighbors)],State)ที่ระบุสำหรับสถานะที่กำหนดและจำนวนเพื่อนบ้านในแต่ละรัฐซึ่งควรเป็นสถานะในการทำซ้ำครั้งถัดไป . cellEvolveอาจเป็นลายเซ็นของcellEvolve :: GameRules -> Cell -> [Cell] -> Cell

  • เหตุผลนี้จะพาคุณไปทำให้evolve :: Board -> Boardกลายเป็นevolve :: GameRules -> Board -> Boardเพื่อให้คุณสามารถใช้evolveการเปลี่ยนแปลงที่มีแตกต่างกันGameRulesแต่คุณอาจจะไปขั้นตอนต่อไปและทำให้cellEvolvepluggable GameRulesแทน

  • การเล่นกับgetCellNeighborsคุณยังสามารถสร้างความเข้าใจevolveทั่วไปเกี่ยวกับBoardโทโพโลยีของ - คุณอาจมีgetCellNeighborsที่ล้อมรอบขอบของบอร์ด, กระดาน 3 มิติ, ฯลฯ


9

หากคุณกำลังเขียน Life Programming เวอร์ชันที่ใช้งานได้คุณต้องเป็นหนี้ให้ตัวคุณเองเพื่อเรียนรู้เกี่ยวกับอัลกอริทึมของ Gosper มันใช้ความคิดจากการเขียนโปรแกรมการทำงานเพื่อให้บรรลุล้านล้านรุ่นต่อวินาทีบนกระดานสี่เหลี่ยมด้านข้างล้านล้าน ฟังดูเป็นไปไม่ได้ที่ฉันรู้ แต่เป็นไปได้อย่างทั่วถึง ฉันมีการนำไปใช้งานใน C # ที่สามารถจัดการกับแผงสี่เหลี่ยมได้อย่างง่ายดาย 2 ^ 64 กำลังสองด้าน

เคล็ดลับคือการใช้ประโยชน์จากกระดานชีวิตที่มีความคล้ายคลึงกันอย่างมากทั้งในเวลาและสถานที่ โดยการบันทึกสถานะในอนาคตของส่วนใหญ่ของกระดานคุณสามารถล่วงหน้าส่วนใหญ่อย่างรวดเร็วในครั้งเดียว

ฉันตั้งใจจะบล็อกผู้เริ่มต้นที่แนะนำอัลกอริทึมของ Gosper เป็นเวลาหลายปีแล้ว แต่ฉันไม่เคยมีเวลาเลย ถ้าฉันทำเช่นนั้นฉันจะโพสต์ลิงค์ที่นี่

โปรดทราบว่าคุณต้องการค้นหาอัลกอริทึมของ Gosper for Lifeไม่ใช่อัลกอริทึมของ Gosper สำหรับการคำนวณผลรวม hypergeometric


ดูน่าสนใจ - ยังคงรอลิงค์นั้นอยู่ ... ... )
jk

3

เป็นเรื่องบังเอิญที่ดีเราได้กล่าวถึงปัญหาที่แน่นอนนี้ในการบรรยายของ Haskell วันนี้ ครั้งแรกที่ฉันเห็น แต่นี่คือลิงค์ไปยังซอร์สโค้ดที่เราได้รับ:

http://pastebin.com/K3DCyKj3


คุณจะอธิบายเพิ่มเติมเกี่ยวกับสิ่งที่มันทำและทำไมคุณถึงแนะนำว่าเป็นการตอบคำถามที่ถาม "คำตอบสำหรับลิงก์เท่านั้น"ไม่ได้รับการต้อนรับอย่างมากที่กองแลกเปลี่ยน
ริ้น

3

คุณอาจต้องการดูการใช้งานบนRosettaCodeเพื่อหาแรงบันดาลใจ

ตัวอย่างเช่นมีฟังก์ชั่น Haskell และ OCaml เวอร์ชั่นที่สร้างบอร์ดใหม่ทุกเทิร์นโดยใช้ฟังก์ชั่นกับอันก่อนหน้านี้ในขณะที่กราฟิก OCaml เวอร์ชั่นใช้สองอาร์เรย์และอัปเดตสลับกันเพื่อความเร็ว

การนำไปใช้งานบางส่วนทำให้ฟังก์ชั่นอัพเดทบอร์ดเสื่อมสภาพไปเป็นฟังก์ชั่นสำหรับการนับจำนวนเพื่อนบ้านใช้กฎชีวิตและวนซ้ำกระดาน สิ่งเหล่านั้นดูเหมือนองค์ประกอบที่มีประโยชน์ในการออกแบบการทำงาน ลองปรับเปลี่ยนบอร์ดเท่านั้นทำให้ทุกอย่างเป็นฟังก์ชั่นที่บริสุทธิ์


1

นี่เป็นเวอร์ชั่นสั้น ๆ ที่ใช้งานได้จริงใน Clojure เครดิตทั้งหมดไปที่ Christophe Grand ผู้เผยแพร่สิ่งนี้ในโพสต์บล็อกของเขา: Game of Life ของ Conway

(defn neighbours [[x y]]
  (for [dx [-1 0 1] 
        dy (if (zero? dx) [-1 1] [-1 0 1])]
    [(+ dx x) (+ dy y)]))

(defn step [cells]
  (set (for [[loc n] (frequencies (mapcat neighbours cells))
             :when (or (= n 3) (and (= n 2) (cells loc)))]
         loc)))

เกมนี้สามารถเล่นได้โดยใช้ฟังก์ชั่น "step" ซ้ำกับชุดของเซลล์เช่น:

(step #{[1 0] [1 1] [1 2]})
=> #{[2 1] [1 1] [0 1]}

ความฉลาดคือส่วน (mapcat เพื่อนบ้านเซลล์) ส่วน - สิ่งนี้จะสร้างรายการแปดเพื่อนบ้านสำหรับแต่ละเซลล์ที่ใช้งานอยู่และเชื่อมต่อพวกเขาทั้งหมดเข้าด้วยกัน จากนั้นจำนวนครั้งที่แต่ละเซลล์ปรากฏในรายการนี้สามารถนับได้ด้วย (ความถี่ .... ) และในที่สุดเซลล์ที่มีการนับความถี่ที่ถูกต้องจะผ่านไปยังรุ่นต่อไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.