Di chuyển người chơi vào cùng một hình vuông?


15

Hãy xem xét một lưới 2 x 2 hình vuông. Một người chơi có thể di chuyển lên một hình vuông nếu:

  • không người chơi nào khác muốn di chuyển vào ô vuông tiếp theo
  • không có người chơi nào khác đã chờ đợi và vẫn đang chiếm lĩnh quảng trường trong lượt này

Sơ đồ ví dụ

Tôi đã bao gồm hình ảnh trên để mô tả vấn đề của tôi.

Người chơi di chuyển đồng thời.

Nếu 2 (hoặc nhiều hơn) người chơi cố gắng di chuyển vào cùng một ô vuông, thì không di chuyển.


1
Người chơi có thể di chuyển đến các ô khác trong một bước không? ví dụ: công tắc màu vàng và màu xanh có thể đặt chính xác trong cùng một bước (màu xanh đi một ô bên trái và màu vàng đi một ô bên phải)?
Ali1S232

Gajet có ngay bây giờ. Nhưng đến một lúc nào đó tôi không muốn 2 người chơi lân cận có thể trao đổi địa điểm trực tiếp
t123

sau đó câu trả lời của tôi giải quyết vấn đề đó.
Ali1S232

2
TUYỆT VỜI có liên quan: kiểm tra các quy tắc di chuyển cho Ngoại giao. vi.wikipedia.org/wiki/Diplomacy_(game)#Movement_phase
TehShrike

Câu trả lời:


11
  1. Gắn cờ tất cả người chơi là đứng yên hoặc di chuyển, tùy thuộc vào việc họ có gửi di chuyển trong lượt này hay không.
  2. Đi qua danh sách di chuyển. Nếu hai lần di chuyển đến cùng một vị trí, hãy xóa chúng khỏi danh sách và đặt người chơi đứng yên.
  3. Lặp qua danh sách loại bỏ tất cả các di chuyển trỏ đến một người chơi đứng yên hoặc chướng ngại vật khác. Làm điều này nhiều lần cho đến khi danh sách không thay đổi khi bạn đi qua nó.
  4. Di chuyển tất cả người chơi.

Tôi nghĩ rằng nên làm việc. Nó chắc chắn hoạt động cho trường hợp bạn đăng, và một vài trường hợp tầm thường khác mà tôi đã thử nghiệm nó.


Vâng, điều này sẽ làm việc. Lưu ý rằng bạn không thực sự muốn lặp lại nhiều lần trong danh sách người chơi; trong thực tế, sẽ hiệu quả hơn nhiều khi giải quyết va chạm bằng cách quay lại.
Ilmari Karonen

16

Giải quyết va chạm, thay vì phòng ngừa va chạm.

Đơn giản chỉ cần di chuyển các đối tượng, sau đó kiểm tra xem đã có bất kỳ va chạm nào chưa. Nếu đã có va chạm với một khối khác di chuyển trở lại hình vuông trước đó, hoặc tùy thuộc vào loại trò chơi, một hình vuông khác.


1
Có nhưng nếu người ta phải di chuyển trở lại thì những người khác cũng sẽ phải di chuyển trở lại ...
t123

2
Bạn đã đúng, nhưng một lần nữa, nó phụ thuộc vào loại trò chơi thực tế, sẽ cần thêm thông tin và tình huống sẽ thay đổi dựa trên loại. Đây là về câu trả lời chung chung nhất có sẵn.
ultifinitus

5
bạn không phải giải quyết tất cả các va chạm trong một bước. di chuyển tất cả các đối tượng, kiểm tra nếu có bất kỳ va chạm di chuyển ngược nào liên quan đến vụ va chạm đó, lặp lại quá trình này cho đến khi không còn va chạm.
Ali1S232

4
Move all players according to their request.
while there are still some squares multiply occupied:
    For each square that is now multiply occupied:
        For each player in that square that moved there this turn:
            Return them to their previous square
            Mark them as having not moved this turn

Điều này đòi hỏi mỗi người chơi phải nhớ nơi họ vừa chuyển đến, để họ có thể được trả lại, và họ cũng nhớ liệu họ có di chuyển lượt này hay không. Kiểm tra thứ hai này có nghĩa là mỗi phần sẽ chỉ cần trả về một lần và phải đảm bảo thuật toán kết thúc đúng. Nó cũng đảm bảo rằng chỉ những người chơi đã di chuyển được trả lại - người cư ngụ ban đầu được ở lại vì họ không được xem xét để xóa.


3

Một giải pháp khác là sử dụng bản đồ lớn gấp 2 lần so với những gì bạn đang hiển thị. mỗi lần bạn muốn di chuyển người chơi, bạn di chuyển họ hai lần để người chơi luôn hạ cánh với giá trị chẵn cho cả X và Y. một lần nữa sẽ có một số trường hợp hiếm hoi cần chú ý hơn nhưng hầu hết các trường hợp có thể được giải quyết (như trường hợp bạn mô tả) mà không cần suy nghĩ hai lần.


Tôi nghĩ rằng bạn có một cái gì đó trong tâm trí, nhưng nó không đi qua trong câu trả lời của bạn. Làm thế nào để sử dụng bản đồ 2x giải quyết vấn đề va chạm?
Zan Lynx

Được chứ. Tôi nghĩ rằng tôi thấy câu trả lời. Hai mảnh di chuyển ngược hướng hạ cánh trên cùng một hình vuông và va chạm. Các mảnh di chuyển xung quanh theo chiều kim đồng hồ di chuyển nửa bước, luôn để lại một không gian mở cho một mảnh khác di chuyển vào.
Zan Lynx

@ZanLynx: đó chính xác là cách nó giải quyết vấn đề, vấn đề duy nhất sẽ là khi hai mảnh (nói màu xanh lá cây và màu xanh) sẽ va chạm và một mảnh khác (màu vàng) sẽ lấp đầy vị trí cuối cùng của màu xanh lá cây. trong những trường hợp tương tự như thế này (nếu có thể), bạn cần giải quyết các va chạm như ultifinitus đã đề xuất.
Ali1S 232

cách thực hiện dễ dàng nhất mà tôi biết để phát hiện va chạm là sự pha trộn giữa tôi và ultifinitus. Của tôi là tốt để kiểm tra nếu các mảnh đang giao nhau và unstifinitus là tốt để giải quyết các loại va chạm khác.
Ali1S 232

0

Đăng ký tất cả các di chuyển được yêu cầu bằng cách sử dụng một mảng hoặc bản đồ.

Nếu có xung đột, hãy hoàn nguyên yêu cầu di chuyển trong câu hỏi. Nếu điều đó trả đối tượng về một hình vuông mà một đối tượng khác đang cố chiếm, hãy hoàn nguyên yêu cầu của đối tượng yêu cầu.

Mã giả:

int[][] game; // game board

var doMoves() {
    int[][] dest = [][]; // destinations; cleared each run

    for (obj in gameObjects)
        if (obj.moveRequest) {
            var o = dest[obj.moveX][obj.moveY];
            if (o) {
                // collision!
                o.doNotMove = true;
                obj.doNotMove = true;
            } else {
                dest[obj.moveX][obj.moveY] = obj;
            }
        }
    }

    // check move validity
    for (obj in gameObjects) {
        if (obj.doNotMove) continue;

        var o = game[obj.moveX][obj.moveY];
        if (o and o.doNotMove)
            revertRequest(obj, dest);
    }

    // process moves
    //etc
}

// recursive function to back up chained moves
var revertRequest(obj, dest) {
    if (!obj.doNotMove) {
        obj.doNotMove = true;
        var next = dest[obj.x][obj.y];
        if (next)
            revertRequest(next, dest);
    }
}

0

Dựa trên câu trả lời của SimonW , đây là một thuật toán rõ ràng:

Đặt squareslà một mảng được lập chỉ mục bởi các vị trí người chơi và chứa, cho mỗi vị trí có thể, hoặc chỉ mục của một vị trí khác hoặc giá trị đặc biệt NULL. (Bạn có thể muốn lưu trữ phần này dưới dạng một mảng thưa thớt.) Các giá trị có thể có của các mục trong mảng này có thể được hiểu như sau:

  • Nếu squares[S]NULL, hình vuông Slà tự do để di chuyển vào.
  • Nếu squares[S] == S, người chơi Skhông thể hoặc sẽ không di chuyển, hoặc hai (hoặc nhiều) người chơi đã cố gắng di chuyển đến Scùng một lúc và đều bị từ chối.
  • Nếu không, squares[S]sẽ chứa chỉ mục của hình vuông mà người chơi muốn chuyển sang hình vuông S.

Trên mỗi lượt, khởi tạo tất cả các mục của squaresđể NULLvà sau đó chạy các thuật toán sau đây:

for each player:
   current := the player's current location;
   target := the location the player wants to move to (may equal current);
   if squares[target] is NULL:
      squares[target] := current;  // target is free, mark planned move
   else
      // mark the target square as contested, and if necessary, follow
      // the pointers to cancel any moves affected by this:
      while not (target is NULL or squares[target] == target):
         temp := squares[target];
         squares[target] := target;
         target := temp;
      end while
      // mark this player as stationary, and also cancel any moves that
      // would require some else to move to this square
      while not (current is NULL or squares[current] == current):
         temp := squares[current];
         squares[current] := current;
         current := temp;
      end while
   end if
end for

Sau đó, lặp lại danh sách người chơi và di chuyển những người có thể làm như vậy:

for each player:
   current := the player's current location;
   if not squares[current] == current:
       move player;
   end if
end for

Vì mỗi lần di chuyển chỉ có thể được lên kế hoạch một lần và hủy nhiều nhất một lần, thuật toán này sẽ chạy trong thời gian O ( n ) cho n người chơi ngay cả trong trường hợp xấu nhất.

(Than ôi, thuật toán này sẽ không ngăn người chơi chuyển đổi địa điểm hoặc băng qua các đường chéo. Có thể điều chỉnh thủ thuật hai bước của Gajet với nó, nhưng cách hoàn toàn ngây thơ để làm như vậy sẽ không hiệu quả và tôi quá mệt mỏi để tìm ra một cách tốt hơn ngay bây giờ.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.