Chess Game.docx

18 774 6
Chess Game.docx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Chess Game

Trang 1

PHẦN I: GIỚI THIỆU TRÒ CHƠI CỜ VUA

- Cờ vua, trước kia còn được gọi là cờ quốc tế, là một trò chơi trên bàn và là một môn thể thao trí tuệ cho 2 người chơi Ngày nay, cờ vua là một trong những trò chơi phổ biến nhất thế giới với hàng triệu người tại nhà riêng, trong câu lạc bộ, trực tuyến, từ xa và trong các giải đấu

- Trò chơi này diễn ra trên một bảng hình vuông, gọi là bàn cờ, gồm 8 hàng (đánh số từ 1 đến 8) và 8 cột (đánh số từ a đến h), tạo ra 64 ô hình vuông với các màu đậm và nhạt xen kẽ nhau, với mỗi người chơi sẽ có ô màu nhạt ở hàng cuối cùng bên tay phải của mình khi ngồi vào bàn chơi cờ Mỗi người sẽ bắt đầu ván cờ với 16 quân cờ và sẽ lần lượt đi các quân của mình sau khi đối phương đã đi xong một nước (hoàn thành nước đi).

Trang 2

-Quy tắc chơi

Khi một ván cờ vua bắt đầu, một người chơi sẽ cầm quân đen và người chơi còn lại cầm quân trắng Việc chọn lựa ai sẽ cầm quân đen hay trắng phụ thuộc vào thể thức chơi là giải trí hay thi đấu trong hệ thống có tổ chức Nó có thể là do hai người thỏa thuận (giải trí) hoặc do quyết định của trọng tài trong giải đấu Bên cầm quân trắng luôn luôn được đi trước và do đó có một ưu thế nhỏ so với bên cầm quân đen Các quân cờ cần phải xếp trên bàn cờ tiêu chuẩn với ô nằm ở hàng cuối cùng bên tay phải người chơi bao giờ cũng có màu nhạt.

-Các quân cờ có nước đi khác nhau:

+ Xe (ký hiệu quốc tế R) di chuyển theo các đường thẳng dọc theo cột hay hàng tới ô còn trống mà không có quân nào cản trên đường đi hay tới ô bị quân đối phương chiếm giữ (ăn quân) nhưng không thể vượt qua quân đang đứng ở ô đó Ngoại lệ duy nhất là trường hợp nhập thành Khi đó nó có thể nhảy qua quân Vua của mình để đứng cạnh nó Chỉ có Xe mới có nước đi như thế

+ Tượng (ký hiệu quốc tế B) di chuyển theo đường chéo tới ô có cùng màu với nguyên lý tương tự như Xe tới ô còn trống hay ô bị quân đối phương chiếm giữ (ăn quân).

+ Hậu (ký hiệu quốc tế Q) có nước đi là tổ hợp đơn giản của chuyển động của Xe và Tượng Trong một nước đi nó có thể di chuyển theo đường chéo hoặc đường thẳng dọc theo cột hay hàng, với nguyên lý đi và ăn quân giống như Tượng và Xe.

+ Mã (ký hiệu quốc tế N) có thể di chuyển tới ô còn trống hay ô bị quân đối phương chiếm giữ (ăn quân) theo dạng hình chữ L Quân Mã không bị cản như trong cờ tướng.

Trang 3

+ Tốt (không cần ký hiệu) có thể di chuyển thẳng về phía trước chỉ một ô một lần tới ô còn trống (đi mà không ăn quân), nhưng khi di chuyển quân để ăn quân đối phương thì đi chéo Ví dụ, Tốt trắng tại ô c4 có quyền ăn quân đối phương tại b5 hoặc d5 nếu một trong hai ô này có quân đối phương chiếm hoặc di chuyển xuống ô c5 nếu ô này còn trống, trừ hai trường hợp sau:

* Nó có thể di chuyển 1 hoặc 2 ô nếu nó đi từ vị trí xuất phát ban đầu tới ô chưa bị chiếm giữ, nhưng không thể nhảy qua một quân khác để tới ô đó Ví dụ Tốt trắng tại g2 có thể đi tới g3 hoặc g4 nếu đây là nước đi đầu tiên của nó và các ô này chưa bị chiếm giữ, nhưng nó không thể đi tới g4 nếu ô g3 đã có một quân nào đó chiếm giữ.

* Trong trường hợp khi một quân Tốt nào đó của bên trắng đạt tới hàng 5 (ví dụ tới ô e5) và quân Tốt thuộc một trong hai cột của bên đen nằm ngay bên cạnh cột mà Tốt trắng này đang chiếm giữ (trong trường hợp đã cho là cột d và cột f) đi từ vị trí xuất phát đầu tiên (d7 hay f7) nhảy liền 2 ô tới ô d5/f5 thì Tốt trắng tại vị trí e5 ngay tại nước đi sau đó có quyền ăn Tốt đen tại ô d5/f5 và di chuyển tiếp tới ô d6/f6 Quyền này sẽ tự động mất, nếu tại nước đi ngay sau đó quân trắng di chuyển quân khác Tương tự như vậy cho Tốt đen khi nó đã chiếm giữ hàng 4 Đây là trường hợp mà trong cờ vua người ta gọi là bắt tốt qua đường (en passant).

*Tốt còn một đặc điểm nữa là khi nó di chuyển đến hàng cuối cùng thì người chơi có quyền phong cấp cho nó thành bất kỳ quân nặng hay nhẹ nào (Hậu, Xe, Tượng, Mã) + Vua (ký hiệu quốc tế là K) là quân quan trọng nhất, nếu mất Vua thì người chơi thua cuộc Mỗi lần đi nó có thể ăn quân hoặc di chuyển sang các ô bao quanh ô mà nó hiện tại đang chiếm giữ, nhưng không thể tới ô mà quân của mình đang chiếm giữ hay các ô bị quân đối phương kiểm soát Ngoại lệ duy nhất là trường hợp nhập thành Khi đó nó có thể di chuyển qua hai ô đồng thời với việc di chuyển quân Xe của mình để quân Xe đó đứng bên cạnh nó về phía cột trung tâm Ký hiệu của nhập thành là 0-0 (nhập thành gần) và 0-0-0 (nhập thành xa)

*Lưu ý: Khi thực hiện nhập thành trên thực tế, theo luật của FIDE, bao giờ cũng phải di chuyển Vua trước và thực hiện bằng một tay duy nhất.

+ Khi ăn quân đối phương, quân tấn công sẽ di chuyển tới ô đó và thay thế cho quân đối

phương tại vị trí này, bắt tốt qua đường (en passant) là ngoại lệ duy nhất Quân bị ăn được

loại ra khỏi bàn cờ Vua không thể không bảo vệ khỏi nước chiếu, do đó khi bị chiếu thì người chơi phải thực hiện các biện pháp nhằm cứu Vua (di chuyển Vua khỏi vị trí bị chiếu, ăn quân đang chiếu hay dùng quân khác của mình cản đường chiếu nếu có thể) Nếu không thể có nước đi để cứu Vua thì người chơi bị chiếu bí và thua cuộc.

Trang 4

+ Các ván cờ không phải bao giờ cũng kết thúc bằng chiếu bí Có thể một bên xin thua, có thể thua do hết giờ hoặc phạm luật chơi Có thể xảy ra các ván cờ hòa Một ván cờ vua là hòa khi: do thỏa thuận của hai bên do không bên nào dám mạo hiểm hay khi không đủ lực lượng để chiếu hết, rơi vào trạng thái hết nước đi (stalemate), cả hai bên lặp lại nước đi ba lần hay luật 50 nước đi (perpetual check).

Trang 5

PHẦN II: CÁC LÝ THUYẾT LIÊN QUAN

Sau đây là quá trình tạo một ứng dụng mạng kiểu TCP

* Tạo ServerSocket

* Gọi thực thi phương thức accept() để chấp nhận thiết lập kết nối với Client => nhận được Socket giao tiếp với Client.

* Lấy InputStream và OutputStream để nhận và gửi dữ liệu với Client.

* Gửi và nhận dữ liệu với Client, sử dụng các phương thức read() và write() của các lớp đối tượng InputStream và OutputStream.

* Đóng Socket và ServerSocket * Kết thúc chương trình

* Tạo Socket kết nối đến Server

* Lấy InputStream và OutputStream để nhận và gửi dữ liệu với Server.

* Gửi và nhận dữ liệu với Server, sử dụng các phương thức read() và write() của các lớp đối tượng InputStream và OutputStream.

* Đóng Socket

* Kết thúc chương trình

Trang 6

I/ SOCKET

Một socket có thể thực hiện bảy thao tác cơ bản:

• Kết nối với một máy ở xa (ví dụ, chuẩn bị để gửi và nhận dữ liệu

• Chấp nhận liên kết từ các máy ở xa trên cổng đã được gán.

Có nhiều kiểu Socket khác nhau tương ứng với mỗi kiểu giao thức được sử dụng để giao tiếp giữa hai máy trên mạng Internet Đối với chồng giao thức TCP/IP, có hai kiểu Socket chính được sử dụng là stream socket và datagram socket Stream socket sử dụng giao thức TCP để cung cấp dịch vụ gửi dữ liệu tin cậy Datagram socket sử dụng giao thức UD để cung cấp dịch vụ gởi gói tin đơn giản Ngôn ngữ lập trình Java hỗ trợ lớp Socket và ServerSocket cho kiểu stream socket và lớp DatagramPacket và DatagramSocket cho kiểu datagram socket Đối với kiểu stream socket, lớp Socket được sử dụng bởi cả client và server Lớp Socket này có các phương thức tương ứng với bốn thao tác đầu tiên của thao tác cơ bản của socket trình bày ở trên Ba thao tác cuối được hỗ trợ bởi server để chờ các client liên kết tới Các thao tác này được cài đặt bởi lớp ServerSocket

II/ TCP SOCKET

Client thiết lập giao tiếp với server và đợi sự đáp trả từ Server Các socket cho client thường được sử dụng theo các bước sau:

• Tạo ra một Socket mới sử dụng hàm khởi tạo với địa chỉ IP và số hiệu cổng dịch vụ của máy đích Socket cố gắng liên kết với socket server của máy đích

• Sau khi liên kết được thiết lập, lấy luồng nhập và luồng xuất được tạo ra giữa socket ở máy gửi - client và socket ở máy đích – server Các luồng này được sử dụng để gửi dữ liệu cho nhau Kiểu liên kết này được gọi là song công (full-duplex) các host có thể nhận và gửi dữ liệu đồng thời Ý nghĩa của dữ liệu phụ thuộc vào giao thức

• Khi việc truyền dữ liệu hoàn thành, một hoặc cả hai phía ngắt liên kết Một số giao thức, như HTTP, đòi hỏi mỗi liên kết phải bị đóng sau mỗi khi yêu cầu được phục vụ Các giao thức khác, chẳng hạn FTP, cho phép nhiều yêu cầu được xử lý trong một liên kết đơn.

Trang 7

III/ INPUT, OUTPUT STREAM

Luồng đơn giản là một lộ trình mà dữ liệu sẽ di chuyển giữa chương trình và các thiết bị nhập xuất, nó là một sự biểu diễn trừu tượng (cấu trúc dữ liệu, lớp) để dữ liệu có thể trao đổi giữa chương trình và các thiết bị vật lý.

Trong java, luồng được thiết kế thành nhiều lớp những tất cả chúng được dẫn xuất ra từ hai lớp trừu tượng đó là InputStream và OutputStream trong gói java.io Có hai loại luồng trong java đó là luồng ký tự và luồng bytes Tất cả các task liên quan đến các lớp nhập xuất trong java nếu có lỗi sẽ quăng ra một IOException.

1)Những lớp Ouput stream

-OutputStream là lớp trừu tượng và cơ bản nhất để tất cả các lớp xử lý luồng xuất byte kế thừa.Nó có 3 phương thức chính là:

• Write ghi những byte dữ liệu tới luồng xuất

• Flush xả luồng để tất cả các vùng nhớ (buffer) của luồng trong trạng thái trống sẵn sàng cho việc ghi

• Close đóng luồng xuất và giải phóng tất cả tài nguyên hệ thống liên quan đến luồng xuất này

Dưới đây là các lớp kế thừa từ lớp OutputStream:

- ObjectOutputStream: được dùng để chuyển đối tượng thành dãy byte và ghi.

- ByteArrayOutputStream là một lớp kế thừa từ lớp OutputStream, nó được dùng để ghi dữ liệu trong một mảng byte, vùng nhớ (buffer) dữ liệu sẽ tự động tăng khi chúng ta ghi dữ liệu vào.

- FileOutputStream là lớp kế thừa từ lớp OutputStream, được dùng để ghi dữ liệu tới tập tin.

- BufferedOutputStream kế thừa từ lớp FilterOutputStream, nó dùng để hỗ trợ việc ghi dữ liệu trong vùng đệm nhằm cải tiến performance khi ghi dữ liệu.

- DataOutputStream giúp ứng dụng ghi những kiểu dữ liệu cơ bản (primitive types) như boolean, int, float,… tới stream Lớp này sinh ra nhằm giúp dễ dàng hơn trong việc ghi dữ liệu có nhiều kiểu như số nguyên, số thực, ký tự…

Trang 8

2)Những lớp Input stream

InputStream là một lớp trừu tượng dùng để các lớp xử lý nhập byte dữ liệu kế thừa InputStream có các hàm sau:

• Available trả về số lượng byte có thể được đọc từ inputStream này • Read đọc byte dữ liệu kế tiếp từ input stream

• Mark đánh dấu vị trí hiện tại trong input stream • Skip không đọc n byte dữ liệu từ input stream

• Reset khởi động lại việc đọc từ vị trí trong phương thức mark

• Close đóng input stream là giải phóng toàn bộ tài nguyên hệ thống liên quan đến stream này

Dưới đây là các lớp kế thừa từ lớp InputStream:

- ObjectInputStream: là lớp đọc dãy byte và chuyển thành đối tượng phù hợp.

- ByteArrayInputStream là lớp dùng để chứa những byte có thể được đọc bởi các stream khác, chúng ta có thể đọc từng ký tự hoặc nhiều ký tự từ stream này Còn nếu đọc tư ByteArrayOutputStream chúng ta chỉ có thể lấy ra một mảng byte, việc đọc dữ liệu trong vùng đệm nhằm cải tiến performance khi đọc dữ liệu.

- DataInputStream là lớp kế thừa từ filterInputStream, nó giúp ứng dụng đọc dữ liệu có kiểu là các kiểu nguyên thủy (primitive types) như int, float, boolean, …

3)Những lớp Reader và Writer

Những lớp thuộc nhóm Reader và Writer dùng để giúp việc nhập xuất các luồng ký tự (character) giữa ứng dụng và các thiết bị vật lý.

Các lớp Reader: Reader, BufferedReader, CharArrayReader, FilterReader, InputStreamReader, StringReader, PipedReader, FileReader, LineNumberReader, PushBackReader

Các lớp Writer: Writer, BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, FileWriter, PipedWriter, PrinterWriter, StringWriter, File, RandomAccessFile, FileDescriptor, FilePermission, StreamTokenizer

Reader và Writer là hai lớp trừu tượng được dùng để các lớp nhập xuất luồng ký tự kế thừa Reader cho việc đọc, còn Writer cho việc ghi.

IV/ THREAD

Mỗi khi chạy một ứng dụng trong Java thì bạn đã có một Thread Đây là Thread chính, nó thực thi các dòng lệnh trong phương thức: public static void main Đây là một điểm nhập bắt buộc cho mọi ứng dụng độc lập.

Trang 9

Để tạo ra một Thread khác ngoài Thread chính trên, Java cung cấp cho chúng ta hai cách : - Tạo ra một lớp con của lớp Thread (java.lang.Thread)

- Tạo ra một lớp hiện thực interface Runnable Chúng ta sẽ tìm hiểu lần lược hai cách trên.

1) Tạo một lớp con của lớp java.lang.Thread

Bạn khai báo như sau : class A extends Thread { public void run() {

// code for the new thread to execute }

} .

A a = new A(); // create the thread object a.start(); // start the new thread executing

- Với cách này các dòng lệnh của bạn sẽ được đặt trong method run() Method này được override method nguyên thuỷ của lớp Thread.Sau đó bạn sẽ tạo ra một đối tượng từ lớp của bạn.Bạn gọi phương thức start() từ đối tượng đó Lúc này Thread của bạn chính thức được tạo ra và phương thức start sẽ tự gọi method run của bạn và thực thi các dòng lệnh mà bạn đã đặc tả.

- Chú ý rằng : method start() là method của hệ thống, nó có nhiệu vụ cấp phát bộ nhớ, tạo ra một Thread và gọi hàm run() của bạn Vì thế bạn không nên override phương thức này Điều này có thể dẫn đến không tạo được Thread.

2) Hiện thực interface Runnable

Bạn khai báo như sau :

class B extends … implements Runnable { public void run() {

// code for the new thread to execute }

} .

B b = new B(); // create the Runnable object Thread t = new Thread(b); // create a thread object t.start(); // start the new thread

- Cũng giống như cách trên, dòng lệnh của bạn đặt trong method run() (có thể gọi đến các phương thức khác, nhưng phải bắt đầu trong phương thức này) Sau đó bạn tạo một đối

Trang 10

tượng B từ lớp đã hiện thực interface Runnable, tạo thêm một đối tượng t của lớp Thread vớithông số cho constructor là đối tượng B.

Sau đó khi bạn gọi phương thức t.start() thì chính thức Thread được tạo ra và phương thức

run() của bạn sẽ được triệu gọi một cách tự động.

Bạn sẽ hỏi tại cách thứ hai vẫn phải tạo ra một đối tượng Thread Vậy tại sao lại đưa ra hai cách hiện thực làm gì ?

Câu trả lời là :

- Bản thân ngôn ngữ Java không hỗ trợ đa thừa kế Bạn chỉ có thể extends từ một lớp duy nhất Nhưng bạn lại có thể implements cùng lúc nhiều interface Khi mà lớp của bạn đã [extends] một lớp nào đó rồi (vd : Applet), thì bạn chỉ có thể implements Runnable để tạo ra Thread.

- Việc extends lớp Thread có thể dẫn đến rủi ro là bạn override các method start(), stop(), thì có thể làm cho việc tạo Thread là không thể Một lời khuyên là nên tạo ra một lớp hiện thực interface Runnable (cách thứ hai) khi muốn tạo ra một Thread Chương trình của bạn sẽ trong sáng và dễ tìm lỗi hơn.

Trang 11

PHẦN III: GIỚI THIỆU CHƯƠNG TRÌNH CỜ VUA

Chương trình cờ vua 2 người chơi bao gồm 1 server và các client Khi client muốn chơi cờ thì client phải đăng ký tới server, mỗi 1 ván cờ sẽ bao gồm 2 người chơi trên 1 bàn cờ, các client giao tiếp với nhau thông qua 1 server Server cờ vua sẽ đảm nhận việc giao tiếp giữa các client, server này sẽ trả về danh sách người dùng đã đăng ký chơi khi có yêu cầu chọn người chơi từ client, khi 2 người chơi bắt đầu chơi thì server sẽ gửi bàn cờ về cho 2 client hiển thị Khi 2 client chơi với nhau thì server sẽ chịu trách nhiệm truyền qua lại bàn cờ cho 2 client khi bàn cờ được cập nhật.

Chương trình gồm 2 project chính: Covua(Client) và Covuaserver(Server)

+ Project Covuaserver: gồm các lớp BanCo.java, NguoiChoi.java, QLBanco.java, Main.java.

+ Project Covua: gồm các lớp BanCo.java, JframeChessClient.java, JpanelBanCo.java, JpanelKetNoi.java, NguoiChoi.java, OCo.java, Main.java.

Ngày đăng: 24/08/2012, 15:42

Tài liệu cùng người dùng

Tài liệu liên quan