2011-02-22 32 views
5

Tôi đang triển khai trò chơi giống như người kiểm tra và tôi cần một chuỗi liệt kê tất cả các hành động pháp lý cho một cấu hình nhất định.Tạo trình lặp hợp chất trong F #

Tôi đã có những chức năng sau đây, dịch trực tiếp từ C#:

seq { 
    for y1 = 0 to BOARDSIZE-1 do 
     for x1 = 0 to BOARDSIZE-1 do 
      for dy = -2 to 2 do 
       for dx = -2 to 2 do 
        let x2 = x1 + dx; 
        let y2 = y1 + dy; 
        let currentMove = new MoveStruct(x1, y1, x2, y2); 
        if (currentMove.SomeCondition = true) then 
          yield currentMove; 
    } 

Nó hoạt động, nhưng nó vụng về, và không hoàn toàn "F # cách", hãy để một mình tôi có một nghi ngờ lén rằng những gì tôi đang làm ở đây không phải là hiệu suất tối ưu.

Điều tôi muốn là "làm phẳng điều này" thành nội dung nào đó sử dụng kết hợp "lặp qua tất cả các ô", "lặp qua tất cả các di chuyển hợp lệ từ ô này".

Và đây là các chức năng tôi hy vọng để kết hợp:

let AllCells = 
    seq { 
     for y=0 to BOARDSIZE-1 do 
      for x=0 to BOARDSIZE-1 do 
       yield (x,y); 
    }; 

let LegalMovesAround(x1,y1) = 
    seq { 
     if board.[x1, y1] = WHITE then 
     for dy = -2 to 2 do 
      for dx = -2 to 2 do 
       let x2 = x1 + dx; 
       let y2 = y1 + dy; 
       let currentMove = new MoveStruct(x1, y1, x2, y2); 
       if (currentMove.DetermineMoveType <> MoveType.ILLEGAL 
        && board.[x2, y2] = NONE) then 
         yield currentMove; 
    } 

tôi sẽ tha cho bạn các chi tiết của những nỗ lực khác nhau của tôi để làm cho nó làm việc, bởi vì không ai trong số họ thành công. Nhưng để làm cho câu chuyện dài ngắn, tốt nhất tôi có thể nghĩ ra là một trình lặp mà trả về một seq với mỗi sản lượng, thay vì phiên bản phẳng mà tôi đang tìm kiếm, nó sẽ trả về một MoveStruct đơn giản.

Bất kỳ ai cũng có ý tưởng tốt về cách kết hợp AllCells và LegalMovesAround (x, y)?

Kính trọng, Aleks

Trả lời

1

Bạn sẽ có thể kết hợp chúng theo cách mà họ đang có và sau đó san bằng, một cái gì đó như thế này:

let validMoves = 
    AllCells 
    |> Seq.collect LegalMovesAround 
    |> Seq.distinct 

Nó có thể không phải là giải pháp tốt nhất hiệu suất-khôn ngoan mặc dù.

EDIT: Mã mẫu cố định theo nhận xét của Tomas

+0

Hãy coi chừng trộn chuỗi lười biếng và tác dụng phụ! Nếu hội đồng quản trị bị đột biến, điều quan trọng là phải hiểu rõ khi nào toàn bộ chuỗi được đánh giá. Gọi Seq.distinct trông nguy hiểm ở đây. – Joh

+0

Không bao giờ nhớ bình luận của tôi ở trên, Seq.distinct sẽ được gọi trước khi đi xuống cây di chuyển. – Joh

+1

Điều này không đánh dấu chọn. Tôi đoán 'legalMovesAround' nên là đối số của' Seq.collect'. –

3

Bạn có thể sử dụng lợi nhuận! trong một biểu thức trình tự mới:

let allLegalMoves = seq { 
    for cell in AllCells do 
    yield! LegalMovesAround cell 
} 
3

Bạn có biết yield! không?

cái gì đó như

seq { 
    for x,y in Allcells do 
     yield! LMA(x,y) 
} 
+0

Giải pháp này cũng hoạt động, ngoại trừ nó trả về một chuỗi với mỗi sản lượng, trong khi tôi muốn nó trả về MoveStruct. Người gọi không cần phải biết chi tiết về việc triển khai. – user627943

+0

Không, nó mang lại MoveStruct. Thử nó. – Brian

+0

Đúng vậy. Làm việc như ma thuật. – user627943

Các vấn đề liên quan