// Undo quân cờ public void Undo(Graphics g) { if (stk_CacNuocDaDi.Count != 0) // nếu stack khác rỗng { // Bỏ nước vừa mới đi đc thêm ở đầu Stack OCo oco = stk_CacNuocDaDi.Pop(); // Đưa vào stack_Undo các nước vừa bỏ ra // Phải khởi tạo lại 1 ô cờ mới để tránh việc tham chiếu cùng vùng nhớ stk_CacNuocUndo.Push(new OCo(oco.Dong, oco.Cot, oco.Vitri, oco.Sohuu)); // gán lại sở hữu vừa bỏ ra _mangOCo[oco.Dong, oco.Cot].Sohuu = 0; // Gán lại lượt đi if (_luotDi == 1) { _luotDi = 2; } else { _luotDi = 1; } // Xóa quân cờ bằng cách vẽ đè lại 1 ô cờ tại chính vị trí cần xóa _banco.XoaQuanCo(g, oco.Vitri, sbDeepSkyBlue); } }
// Đánh cờ public bool DanhCo(int mouseX, int mouseY, Graphics g) { // Lấy vị trí x hiện tại / độ rộng ra vị trí cột // Lấy vị trí y / độ cao ra vị trí dòng // Đã test bằng Paint. /// Chặn việc vẽ ô cờ ngay đường biên /// Tại những vị trí là bội của 25. Ví dụ 25, 50, 75... if (mouseX % OCo._chieurong == 0 || mouseY % OCo._chieucao == 0) { return(false); // không đánh cờ } int cot = mouseX / OCo._chieurong; int dong = mouseY / OCo._chieucao; // Nếu 1 ô đã đánh rồi thì không đc phép đánh nữa if (_mangOCo[dong, cot].Sohuu != 0) { return(false); } switch (_luotDi) { case 1: _mangOCo[dong, cot].Sohuu = 1; // Player 1 _banco.VeQuanCo(g, _mangOCo[dong, cot].Vitri, sbBlack); // Quân đen // Sau khi đánh, đổi lại lượt đi _luotDi = 2; break; case 2: _mangOCo[dong, cot].Sohuu = 2; // Player 2 _banco.VeQuanCo(g, _mangOCo[dong, cot].Vitri, sbWhite); // Quân trắng // Sau khi đánh, đổi lại lượt đi _luotDi = 1; break; default: MessageBox.Show("Err!"); break; } // Mỗi lần đánh cờ, sẽ tạo mới danh sách Undo, Khóa không cho người chơi Undo lại. stk_CacNuocUndo = new Stack <OCo>(); // Khởi tạo 1 ô cờ mới để tránh tham chiếu con trỏ cùng vùng nhớ, phát sinh ra các lỗi không mong muốn OCo oco = new OCo(_mangOCo[dong, cot].Dong, _mangOCo[dong, cot].Cot, _mangOCo[dong, cot].Vitri, _mangOCo[dong, cot].Sohuu); // mỗi lần đánh sẽ lưu lại các nước đã đi stk_CacNuocDaDi.Push(_mangOCo[dong, cot]); return(true); }
// Khởi tạo mảng các ô cờ public void KhoiTaoMangOCo() { for (int i = 0; i < _banco.Sodong; i++) { // Do i chạy dọc xuống từng dòng // j chạy ngang trên mỗi dòng // Nên Point sẽ là (j * Chieurong, i * Chieucao) for (int j = 0; j < _banco.Socot; j++) { _mangOCo[i, j] = new OCo(i, j, new Point(j * OCo._chieurong, i * OCo._chieucao), 0); } } }
// Redo quân cờ public void Redo(Graphics g) { if (stk_CacNuocUndo.Count != 0) // nếu stack khác rỗng { // Bỏ nước vừa mới đi đc thêm ở đầu Stack OCo oco = stk_CacNuocUndo.Pop(); // Đưa vào stack_DaDi ôcờ muốn Undo lại stk_CacNuocDaDi.Push(new OCo(oco.Dong, oco.Cot, oco.Vitri, oco.Sohuu)); // gán lại sở hữu chính là sở hữu hiện tại của ô cờ _mangOCo[oco.Dong, oco.Cot].Sohuu = oco.Sohuu; // Xóa quân cờ bằng cách vẽ đè lại 1 ô cờ tại chính vị trí cần xóa // Gán lại lượt đi if (_luotDi == 1) { _luotDi = 2; } else { _luotDi = 1; } _banco.VeQuanCo(g, oco.Vitri, oco.Sohuu == 1 ? sbBlack : sbWhite); } }