12/08/2018, 16:21

Làm game cờ vua online với Rails cable

Xin chào các bạn, trong bài viết lần này mình sẽ giới thiệu với các bạn demo của ứng dụng chơi cờ vua online sử dụng Rails 5 cable và thư viện chess.js. Bài viết được tổng hợp từ nhiều nguồn (bên dưới bài viết) và tự nghiên cứu của cá nhân mình. I. Tổng quan về Rails cable và game cờ vua Bản ...

Xin chào các bạn, trong bài viết lần này mình sẽ giới thiệu với các bạn demo của ứng dụng chơi cờ vua online sử dụng Rails 5 cable và thư viện chess.js. Bài viết được tổng hợp từ nhiều nguồn (bên dưới bài viết) và tự nghiên cứu của cá nhân mình. I. Tổng quan về Rails cable và game cờ vua Bản Rails 5 ra mắt lần này có bổ sung tính năng Web socket, đây là một tính năng khá hay và mạnh mẽ, hỗ trợ giao tiếp hai chiều giữa client và server bằng cách tạo 1 kết nối bằng giao thức TCP socket . Để học hỏi thêm về công nghệ này, mình chọn game cờ vua để viết ví dụ. Cờ vua là game cần 2 người chơi cho 1 trân đấu. 2 người chơi sẽ thi đấu với nhau trực tuyển qua mạng nên việc sử dụng websocket tạo một kênh kết nối giữa 2 người chơi là rất hợp lý. II. Viết demo game cờ vua Trước hết chúng ta cần khởi tạo một project Rails như sau:

rails new Rails5ChessDemo

Để tạo ra bàn cờ vua ở mỗi máy client của người chơi, mình sử dụng thư viện chessboard, download tại địa chỉ http://chessboardjs.com/. Sau khi download về đuợc file min.js, các bạn thêm thư viện vào project bằng cách thêm vào file application.js

//= chessboard.min

Sau đó, chúng ta thêm dòng sau vào file html để hiển thị bàn cờ vua trên view (trong dự án này ta sẽ thêm vào file app/views/welcome/index.html.erb.

<div id="board2" style="awidth: 400px"></div>
<input type="button" id="startBtn" value="Start" />
<input type="button" id="clearBtn" value="Clear" />

Ở file js, chúng ta thêm đoạn sau

var board2 = ChessBoard('board2', {
  draggable: true,
  dropOffBoard: 'trash',
  sparePieces: true
});
$('#startBtn').on('click', board2.start);
$('#clearBtn').on('click', board2.clear);

Đoạn code trên cho phép chúng ta có thể kéo thả các quân cờ đến vị trí bất kì, nút start bắt đầu chơi và nút clear để xóa các quân cờ. Tuy nhiên thư viện này chưa giúp chúng ta kiếm tra các nước đi của quân cờ hợp lệ hay thực hiện các thao tác như ăn quân đối phương và kiểm tra chiếu hết nước (game over). Để thực hiện được các việc trên, chúng ta cần thêm thư viện chess.js (https://github.com/jhlywa/chess.js).

Tương tự thư viện chessboard, các bạn có thể tải chess.js và thêm vào file application.js hoặc sử dụng cdn để thêm thư viện vào project của mình như sau

<script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.2/chess.js"></script>

Thư viện chess cung cấp cho chúng ta các hàm cần thiết để xử lí game cờ vua, điển hình chúng ta thuờng sử dụng 1 số hàm sau:

.game_over(): Hàm này sẽ trả về true khi game kết thúc (bao gồm bị chiếu hết, trận đấu hòa hoặc vào thế bí). .in_check(): Trả về trạng thái đang bị chiếu tuớng. .history([ options ]): Trả về danh sách lịch sử các nuớc đi, nếu truyền tham số vebose = true, chúng ta sẽ nhận đuợc danh sách lịch sử các nước đi, ví dụ như sau:

var chess = new Chess();
chess.move('e4');
chess.move('e5');
chess.move('f4');
chess.move('exf4');

chess.history();
// -> ['e4', 'e5', 'f4', 'exf4']

chess.history({ verbose: true });
// -> [{ color: 'w', from: 'e2', to: 'e4', flags: 'b', piece: 'p', san: 'e4' },
//     { color: 'b', from: 'e7', to: 'e5', flags: 'b', piece: 'p', san: 'e5' },
//     { color: 'w', from: 'f2', to: 'f4', flags: 'b', piece: 'p', san: 'f4' },
//     { color: 'b', from: 'e5', to: 'f4', flags: 'c', piece: 'p', captured: 'p', san: 'exf4' }]

Ngoài ra còn 1 số hàm khác tuy nhiên không quá quan trọng, các bạn có thể tìm hiểu thêm trên github của thư viện chess nhé.

Bây giờ chúng ta sẽ tạo routes và controller để người chơi có thể vào chơi cùng nhau. Tạo controller welcome

rails g controller welcome

Tạo router đến controller.

# config/routes.rb
Rails.application.routes.draw do
  root to: "welcome#index"
  mount ActionCable.server => "/cable"
end

File view hiển thị bàn cờ vua chúng ta đã tạo bên trên rồi nên bây giờ k cần nữa             </div>
            
            <div class=

0