Bài viết này giả định rằng bạn đã hiểu rõ những điều cơ bản của XForms. Để ôn luyện, hãy xem phần Tài nguyên để có các liên kết đến nội dung giúp bạn bắt đầu. Mã này đã được viết và thử nghiệm trên các phần mở rộng XForms của Mozilla Firefox, nhưng các khái niệm này áp dụng cho bất kỳ các công cụ nào. Để làm theo cùng với bài viết này, bạn sẽ cần một trình duyệt có hỗ trợ XForms -- bài viết này được viết bằng cách sử dụng phần mở rộng Mozilla và XForms -- và một máy chủ có hỗ trợ PHP. Để tạo ra các trò chơi câu đố Sudoku mới, bạn cũng sẽ cần có Python đã cài đặt, và chương trình Python Sudoku.
Làm thế nào bạn nhận được như ở đây
Trong Phần 1, bạn tạo ra trò chơi cơ bản, cho phép người chơi chơi Sudoku bằng cách sử dụng các trình đơn thả xuống đơn giản. Các nút Submit (Trình lên) đã không xuất hiện cho đến khi người chơi đã thành công trong việc giải trò chơi câu đố này. Cấu trúc của tài liệu XForms thực tế trông như Liệt kê 1.
Liệt kê 1. Trang hiện tại
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:s="http://www.example.com/sudoku"
xmlns:b="http://www.example.com/board">
<head>
<title>Sudoku</title>
<xforms:model>
<xforms:instance id="content">
<s:game>
<s:row><s:box ro="yes">6</s:box><s:box></s:box>
<s:box></s:box><s:box></s:box><s:box></s:box>
<s:box ro="yes">9</s:box><s:box></s:box><s:box></s:box>
<s:box ro="yes">1</s:box></s:row>
...
<s:square><s:box>0</s:box><s:box>0</s:box><s:box>0</s:box>
<s:box>0</s:box><s:box>0</s:box><s:box>0</s:box><s:box>0
</s:box>
<s:box>0</s:box><s:box>0</s:box></s:square>
...
<s:submitButtonElement>Submit</s:submitButtonElement>
<s:correctRows>no</s:correctRows>
</s:game>
</xforms:instance>
<xforms:bind nodeset="//s:row//s:box[@ro='yes']" readonly="true()" />
<xforms:bind nodeset="//s:submitButtonElement"
relevant="/s:game/s:correctRows = 27" />
<xforms:bind nodeset="//s:correctRows" calculate=
"count(/s:game/s:row[s:box = '1'][s:box = '2'][s:box = '3']
[s:box = '4'][s:box = '5'][s:box = '6'][s:box = '7'][s:box = '8']
[s:box = '9']) +
count(/s:game[s:row[s:box[1]='1']][s:row[s:box[1]='2']]
[s:row[s:box[1]='3']][s:row[s:box[1]='4']][s:row[s:box[1]='5']]
[s:row[s:box[1]='6']][s:row[s:box[1]='7']][s:row[s:box[1]='8']]
[s:row[s:box[1]='9']]) +
...
count(/s:game/s:square[s:box = '1'][s:box = '2']
[s:box = '3'][s:box = '4'][s:box = '5'][s:box = '6']
[s:box = '7'][s:box = '8'][s:box = '9'])" />
<xforms:instance id="templates">
<b:template>
<b:entry><b:sendvalue>0</b:sendvalue>
<b:display></b:display></b:entry>
<b:entry><b:sendvalue>1</b:sendvalue>
<b:display>1</b:display></b:entry>
<b:entry><b:sendvalue>2</b:sendvalue>
<b:display>2</b:display></b:entry>
...
</b:template>
</xforms:instance>
<xforms:submission id="submitgame" action="" method="post"/>
</xforms:model>
<style type="text/css">
div > * {display: inline;}
*:read-only { color: red }
</style>
</head>
<body>
<img src="images/showlayout.gif" style="float:left;height: 64px; width: 64px;" />
<h1 align="center">Sudoku</h1>
<br clear="left" />
<div>
<xforms:repeat id="gamerow" nodeset="instance('content')/s:row">
<xforms:repeat id="gamebox" nodeset="s:box">
<span class="test"><xforms:select1 ref=".">
<xforms:itemset nodeset="instance('templates')/b:entry">
<xforms:label ref="b:display"/>
<xforms:value ref="b:sendvalue"/>
</xforms:itemset>
</xforms:select1></span>
</xforms:repeat>
</xforms:repeat>
</div>
Correct Rows: <xforms:output ref="//s:correctRows" /><br />
<xforms:trigger style="display:block">
<xforms:label>Check it!</xforms:label>
<xforms:action ev:event="DOMActivate">
<xforms:setvalue ref="/s:game/s:square[1]/s:box[1]"
value="/s:game/s:row[1]/s:box[1]" />
<xforms:setvalue ref="/s:game/s:square[1]/s:box[2]"
value="/s:game/s:row[1]/s:box[2]" />
...
</xforms:action>
</xforms:trigger>
<xforms:submit ref="/s:game/s:submitButtonElement"
submission="submitgame">
<xforms:label>Submit</xforms:label>
</xforms:submit>
</body>
</html> |
Tóm tắt, cá thể trò chơi này bao gồm một phần tử
row cho mỗi hàng của mạng lưới ô vuông, và các
phần tử square (ô vuông) để giúp mô phỏng các
hàng cho việc tính toán các ô vuông 3x3 trên mạng lưới này. (Xem Phần 1 nếu bạn cần ôn lại về các quy tắc này). Liên kết phần tử
correctRows với một tính toán cho phép bạn biết
có bao nhiêu hàng, cột, và ô vuông đã được giải đúng. Khi tổng số lượt
nhập là 27, nút Submit xuất hiện.
Để tạo mạng lưới ô vuông, hãy tạo vòng lặp qua mỗi
row, và với mỗi box,
tạo một danh sách thả xuống bằng cách tạo vòng lặp thông qua của các phần
tử entry (nhập vào) trong cá thể
templates (các khuôn mẫu). Nếu phần tử
box có một giá trị, giá trị đó được chọn theo
mặc định. Ngoài ra, nếu cá thể ban đầu cung cấp một số, ô vuông đó trên
mạng lưới ô vuông là chỉ đọc.
Bảng trò chơi trông giống như Hình 1.
Hình 1. Trò chơi hiện tại
Bây giờ chúng ta hãy di chuyển lên.
Bây giờ, sau khi bạn chơi trò chơi này một lúc, bạn có thể sẽ cảm thấy mệt mỏi vì sử dụng các trình đơn thả xuống. Thay vào đó, chỉ cần ghép vào số đúng còn dễ hơn. Để cho những người chơi làm điều đó, bạn không chỉ cơ cấu lại biểu mẫu này, mà còn tạo ra cách để giữ không cho họ nhập vào các giá trị không hợp lệ.
Hãy bắt đầu bằng cách gỡ bỏ các trình đơn thả xuống (xem Liệt kê 2).
Liệt kê 2. Thay thế các trình đơn thả xuống bằng các ô vuông văn bản
...
<xforms:model>
<xforms:instance id="content">
<s:game xmlns:s="http://www.example.com/sudoku">
<s:row><s:box s:ro="yes">6</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box s:ro="yes">9</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box s:ro="yes">1</s:box></s:row>
...
<s:square><s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box><s:box>.
</s:box>
<s:box>.</s:box><s:box>.</s:box></s:square>
...
<s:submitButtonElement>Submit</s:submitButtonElement>
<s:correctRows>no</s:correctRows>
</s:game>
</xforms:instance>
...
<style type="text/css">
@namespace xforms url(http://www.w3.org/2002/xforms);
div > * {display: inline;}
*:read-only { color: red }
xforms|input .xf-value, .input-value {width: 30px;
background-color: white;}
</style>
</head>
<body>
<img src="images/showlayout.gif" style="float:left;height: 64px; width: 64px;" />
<h1 align="center">Sudoku</h1>
<br clear="left" />
<div>
<xforms:repeat id="gamerow" nodeset="instance('content')/s:row">
<xforms:repeat id="gamebox" nodeset="s:box">
<span>
<xforms:input ref="." />
</span>
</xforms:repeat>
</xforms:repeat>
</div>
...
|
Bắt đầu ở phía dưới cùng, lưu ý rằng phần tử
select1 đã được thay thế bằng một phần tử
input (đầu vào) đơn giản, sẽ bao gồm các nội
dung của phần tử box làm giá trị của nó. Thông
thường, phần tử này sẽ diễn tả rộng hơn nhiều so với bạn cần nó, vì vậy
sau đó bạn sẽ sử dụng các CSS (Bảng định kiểu xếp chồng) để thiết lập độ
rộng của giá trị của nó. Lưu ý rằng trước tiên bạn phải khai báo bí danh
vùng tên xforms và vùng tên.
Cuối cùng, một sự thay đổi dữ liệu thực tế đã được thực hiện. Trước đây, bạn sử dụng các số không để chỉ thị các ô vuông mà người chơi phải điền vào, nhưng vì bây giờ bạn đang đặt giá trị thực tế trong ô vuông đó -- bạn không còn thích một nhãn nữa, như trước đây -- bạn đã thay đổi nó thành một dấu chấm (.) để thấy rõ hơn những gì đang xảy ra. Bạn có thể xem kết quả trong Hình 2.
Hình 2. Sử dụng các đầu vào văn bản
Bây giờ, vấn đề ở đây là không có gì ngăn cản không cho một người chơi nhập vào một giá trị vô nghĩa, ví dụ như "42" hoặc "bleh". May mắn thay, bạn có thể giải quyết điều đó.
XForms có sẵn việc xác nhận hợp lệ lược đồ, vì vậy thật dễ dàng cho bạn đặt ra các ràng buộc về những gì mà người chơi có thể nhập vào trong các ô vuông văn bản đó. Ví dụ, bạn có thể quy định các phần tử đầu vào phải là các số nguyên (xem Liệt kê 3).
Liệt kê 3. Ràng buộc đầu vào theo các số nguyên
...
<xforms:instance id="content">
<s:game xmlns:s="http://www.example.com/sudoku"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<s:row><s:box xsi:type="xsd:int"
s:ro="yes">6</s:box><s:box xsi:type="xsd:int"
>.</s:box><s:box xsi:type="xsd:int" >.</s:box>
<s:box xsi:type="xsd:int" >.</s:box><s:box
xsi:type="xsd:int" >.</s:box><s:box xsi:type="xsd:int"
s:ro="yes">9</s:box><s:box xsi:type="xsd:int" >.</s:box>
<s:box xsi:type="xsd:int" >.</s:box><s:box xsi:type="xsd:int"
s:ro="yes">1</s:box></s:row>
...
</s:game>
</xforms:instance>
...
<div>
<xforms:repeat id="gamerow" nodeset="instance('content')/s:row">
<xforms:repeat id="gamebox" nodeset="s:box">
<span>
<xforms:input ref=".">
<xforms:action ev:event="xforms-invalid">
<xforms:setvalue ref=".">.</xforms:setvalue>
<xforms:message level="modal">Please
choose an integer from 1 to
9.</xforms:message>
</xforms:action>
</xforms:input>
</span>
</xforms:repeat>
</xforms:repeat>
</div>
...
|
Trước hết, bạn đang gõ cá thể này vào với vùng tên Lược đồ XML (XML Schema), và quy định rằng các phần tử box phải là các số nguyên. Nhưng không có điểm nào quy định điều đó trừ khi biểu mẫu hành động nếu dữ liệu không phù hợp.
Để nhận được biểu mẫu hành động, bạn có thể chỉ rõ một hành động được thực
hiện nếu phần tử đầu vào xảy ra sự kiện
xforms-invalid Khi nó xảy ra, biểu mẫu thiết
lập giá trị của nó trở lại dấu chấm đơn giản và hiển thị một thông
báo.
Bạn có thể kiểm tra điều này bằng cách thêm một giá trị không phải số nguyên, bạn có thể thấy trong Hình 3.
Hình 3. Nhập các giá trị không hợp lệ
Bây giờ, nếu bạn đã thử nghiệm điều này rồi, thì bạn có thể nhận thấy rằng thực sự bạn đã nhận được hộp thoại thông báo hai lần. Điều này là do bạn đang thiết lập giá trị cho một số không phải số nguyên, chính nó đã không hợp lệ.
May mắn thay, có một tùy chọn khác. Bạn có thể tạo một lược đồ quy định tất cả các giá trị được phép (xem Liệt kê 4).
Liệt kê 4. Lược đồ
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/sudoku"
xmlns="http://www.example.com/sudoku">
<xsd:element name="game" type="GameType"/>
<xsd:element name="row" type="RowType"/>
<xsd:element name="square" type="RowType"/>
<xsd:element name="box" type="BoxType"/>
<xsd:element name="submitButtonElement" type="ButtonType" />
<xsd:element name="correctRows" type="CorrectRowsType" />
<xsd:simpleType name="ButtonType">
<xsd:restriction base="xsd:string" />
</xsd:simpleType>
<xsd:simpleType name="CorrectRowsType">
<xsd:restriction base="xsd:int" />
</xsd:simpleType>
<xsd:simpleType name='BoxType'>
<xsd:restriction base="xsd:string">
<xsd:enumeration value = "."/>
<xsd:enumeration value = "1"/>
<xsd:enumeration value = "2"/>
<xsd:enumeration value = "3"/>
<xsd:enumeration value = "4"/>
<xsd:enumeration value = "5"/>
<xsd:enumeration value = "6"/>
<xsd:enumeration value = "7"/>
<xsd:enumeration value = "8"/>
<xsd:enumeration value = "9"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="RowType">
<xsd:sequence>
<xsd:element ref="box" minOccurs="9" maxOccurs="9" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="GameType">
<xsd:sequence>
<xsd:element ref="row" minOccurs = "9" maxOccurs="9" />
<xsd:element ref="square" minOccurs = "9" maxOccurs="9" />
<xsd:element ref="submitButtonElement" minOccurs="1"
maxOccurs="1" />
<xsd:element ref="correctRows" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema> |
Cụ thể, bạn quy định phần tử box phải là một
trong các số nguyên từ 1 đến 9, hoặc dấu chấm. Sau đó, bạn có thể lưu trữ
lược đồ này trong một tệp, sudoku.xsd, và tham khảo nó từ biểu mẫu (xem
Liệt kê 5).
Liệt kê 5. Đính kèm lược đồ
...
<head>
<title>Sudoku</title>
<xforms:model schema="./sudoku.xsd">
<xforms:instance id="content">
<s:game xmlns:s="http://www.example.com/sudoku"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<s:row><s:box s:ro="yes">6</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box s:ro="yes">9</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box s:ro="yes">1</s:box></s:row>
... |
Bây giờ, nếu bạn chạy biểu mẫu này, bạn vẫn sẽ thấy hộp thoại cảnh báo, nhưng chỉ có một lần, vì theo lược đồ này giá trị mới được phép.
Chắc chắn, bây giờ bạn đã nhận được giao diện đã chỉnh sửa, chúng ta hãy nói về cách quản lý trò chơi mà bạn đang trình bày cho người chơi.
Bước đầu tiên là cho phép người chơi lưu trò chơi hiện tại. Trong một biểu mẫu HTML truyền thống, việc này có nghĩa là các kịch bản lệnh phức tạp chấp nhận dữ liệu và lưu nó, sau đó thêm nhiều kịch bản lệnh hơn để lại lấy ra nó. May mắn thay, XForms làm cho việc này trở nên đơn giản hơn nhiều.
XForms cho phép bạn sử dụng phương thức "PUT" của HTTP để lưu dữ liệu cá thể vào một vị trí cụ thể. Nếu máy chủ Web của bạn được cấu hình đúng, bạn có thể lưu cá thể đó ở đó, nhưng thường lưu dữ liệu vào ổ đĩa cứng cục bộ (xem Liệt kê 6).
Liệt kê 6. Lưu vào một tệp cục bộ
...
<xforms:submission id="submitgame" action="" method="post"/>
<xforms:submission id="savegame" action="file:///c:/sudoku.txt"
replace="instance" instance="content" method="put"/>
</xforms:model>
...
<xforms:submit ref="/s:game/s:submitButtonElement" submission="submitgame">
<xforms:label>Submit</xforms:label>
</xforms:submit>
<xforms:submit submission="savegame">
<xforms:label>Save current game</xforms:label>
</xforms:submit>
</body>
</html>
|
Ở đây bạn đã tạo ra một phần tử submission
(trình lên) mới để chỉ rõ cá thể content (nội
dung), và ra lệnh cho biểu mẫu không thay thế trang này, mà chỉ thay thế
cá thể, với bất kỳ dữ liệu được trả về nào. Tuy nhiên, trong trường hợp
này, không có bất kỳ dữ liệu được trả về, vì nó cũng chỉ rõ phương thức
PUT và vị trí cho tệp đó. Điều này có nghĩa rằng khi bạn nhấn chuột vào
nút đó, nó chỉ đơn giản lưu dữ liệu cá thể vào một tệp XML ở vị trí mà bạn
đã chỉ định.
Nếu bạn lưu và tải biểu mẫu này, bạn sẽ thấy nút mới đó (xem Hình 4).
Hình 4. Nút Save
Thay đổi một vài giá trị và nhấn chuột vào nút Save (Lưu). Bạn sẽ thấy một tệp XML mới trong thư mục gốc của ổ đĩa C: của bạn đang chứa tài liệu cá thể như nó đã có khi bạn đã lưu nó. Bây giờ chúng ta hãy xem xét nó lại.
Một khi bạn đã lưu một trò chơi, việc tải nó lại là khá đơn giản. Việc bạn
muốn làm là có biểu mẫu đưa ra một yêu cầu HTTP và đặt dữ liệu vào trong
cá thể. Bạn có thể làm điều đó bằng cách tạo phần tử
submission khác (xem Liệt kê 7).
Liệt kê 7. Tải dữ liệu
...
<xforms:submission id="savegame" action="file:///c:/sudoku.txt"
replace="instance" instance="content" method="put"/>
<xforms:submission id="loadgame" action="file:///c:/sudoku.txt"
replace="instance" instance="content" method="get"/>
</xforms:model>
<style type="text/css">
...
<xforms:submit submission="savegame">
<xforms:label>Save current game</xforms:label>
</xforms:submit>
<xforms:submit submission="loadgame">
<xforms:label>Load saved game</xforms:label>
</xforms:submit>
</body>
</html> |
Trong trường hợp này, bạn đang đưa ra một yêu cầu
GET đó là điều mà trình duyệt của bạn làm bất
cứ khi nào bạn yêu cầu một trang Web mới. Khi nhận lại dữ liệu, nó chỉ
thay thế các nội dung của cá thể nội dung. Để thấy yêu cầu này đang hoạt
động, hãy lưu và tải biểu mẫu, sau đó thay đổi một vài giá trị. Lưu trò
chơi, rồi tải lại biểu mẫu để đưa nó trở lại trạng thái ban đầu của nó.
Nhấn vào nút Load saved game (Tải trò chơi đã lưu) để thấy các thay
đổi của bạn xuất hiện lại.
Chắc chắn, bây giờ đây là một trò chơi thú vị và hơn nữa, nhưng bạn có thể chơi bao lâu? Không, bạn cần một cách để cho phép người chơi trình lên trò chơi hiện tại cho máy chủ và nhận được một trò chơi mới. Bạn sẽ xem xét việc trình lên thực tế tại một thời điểm, nhưng trước tiên bạn cần chỉnh sửa các thiết lập trình duyệt của bạn một chút.
Vì lý do an toàn, XForms chỉ có thể tải và lưu dữ liệu từ máy chủ mà từ đó nó đã được tải về ban đầu. Bây giờ, bạn có thể giải quyết một phần vấn đề bằng cách tải biểu mẫu lên máy chủ mà bạn sẽ yêu cầu dữ liệu từ đó. Nhưng nó không giải quyết tất cả các vấn đề của bạn.
Khó khăn thực sự là bạn đang lưu dữ liệu vào một tệp cục bộ, có nghĩa là nó không phải là máy chủ gốc. Để giải quyết vấn đề đó, bạn cần phải thêm máy chủ vào danh sách "các máy chủ tin cậy" có liên quan đến XForms.
Để làm điều đó, chọn Tools->Options và chắc chắn đánh dấu chọn hộp kiểm tra "Allow XForms to access other domains" (Cho phép XForms truy cập các miền khác). Tiếp theo, nhấn vào nút Allowed Sites (Các trang được phép). Thêm tên của máy chủ mà bạn đang làm việc với nó và đánh dấu chọn hộp kiểm tra Load and Save (Tải và Lưu). (Xem Hình 5.) Nhấn vào nút Add (Thêm) và đóng các hộp thoại lại. Khởi động lại trình duyệt để nhận được các thay đổi có hiệu lực.
Hình 5. Các trang tin cậy
Bây giờ bạn đã tạo ra việc trình lên thực tế. Cuối cùng, bạn sẽ bắt đầu các
trò chơi mới của mình từ kích bản lệnh
convertGame.php -- bạn cần xem xét kịch bản
lệnh đó một chút -- vì thế hãy tiến lên và cập nhật phần tử
submission này (xem Liệt kê 8).
Liệt kê 8. Trình lên toàn bộ
...
</xforms:instance>
<xforms:submission id="submitgame"
action="http://www.backstopmedia.com/sudoku/convertGame.php"
replace="instance" instance="content" method="post"/>
<xforms:submission id="savegame" action="file:///c:/sudoku.txt"
replace="instance" instance="content" method="put"/>
... |
Cũng như trước đây, bạn đã quy định rằng bạn chỉ muốn thay thế cá thể, chứ không phải toàn bộ trang, và đã chỉ rõ cá thể mà bạn muốn thay thế. Bạn cũng đã thêm vào địa chỉ URL cho kịch bản lệnh sẽ cung cấp các trò chơi mới của bạn.
Trừ khi bạn là một tay cừ khôi về toán học (hoặc muốn có nhiều thời gian thực hành), bạn sẽ không muốn tự mình tạo ra các trò chơi câu đố này. May mắn thay, bạn không phải làm.
Python Sudoku là một ứng dụng mã nguồn mở vừa tạo ra và vừa giải các trò chơi câu đố Sudoku. (Xem phần Tài nguyên để biết địa chỉ URL tải về). Nó được dự định để tạo ra các trò chơi câu đố trên báo và các ứng dụng khác, nhưng bạn sẽ cần thực hiện tinh chỉnh nhỏ -- và một máy chủ có hỗ trợ tạo kịch bản Python -- để làm cho nó tạo ra các câu đố trực tiếp theo dạng mẫu của bạn.
Thay vào đó, bạn sẽ tạo ra một số trò chơi câu đố không nối mạng (offline) và trả về chúng một cách ngẫu nhiên theo biểu mẫu. Để tạo ra các trò chơi câu đố này, hãy giải nén gói Python Sudoku và thực hiện lệnh sau từ thư mục mới được trích xuất (xem Liệt kê 9).
Liệt kê 9. Tạo một trò chơi câu đố mới
>>>>>python pysdk.py -c game11.sdk Creating sudoku... success! 1 _ _ _ _ _ 5 _ _ _ _ _ 6 _ _ 9 _ _ _ _ _ 3 4 _ _ _ _ _ _ _ _ _ _ _ 1 _ _ 8 _ _ _ 2 _ _ 9 7 9 2 _ _ 5 _ _ _ _ _ 8 _ 3 _ _ 6 _ _ _ _ _ _ _ _ _ _ _ 2 4 1 _ 8 _ 3 _ |
Trong trường hợp này, tôi đã tạo ra một tệp gọi là game11.sdk. Hãy tạo ra một loạt các trò chơi câu đố này và đặt tên chúng là game1.sdk, game2.sdk, game3.sdk, và v.v.
Tất cả các tệp đều sử dụng cùng định dạng (xem Liệt kê 10).
Liệt kê 10. Trò chơi được tạo ra
# boardsize 3 x 3 1 0 0 0 0 0 5 0 0 0 0 0 6 0 0 9 0 0 0 0 0 3 4 0 0 0 0 0 0 0 0 0 0 0 1 0 0 8 0 0 0 2 0 0 9 7 9 2 0 0 5 0 0 0 0 0 8 0 3 0 0 6 0 0 0 0 0 0 0 0 0 0 0 2 4 1 0 8 0 3 0 |
Một khi bạn đã tạo ra các trò chơi, hãy di chuyển chúng đến một máy chủ mà trên đó bạn có thể thực thi PHP. Bạn sẽ tạo ra một kịch bản lệnh PHP, convertGame.php, chọn một tệp ngẫu nhiên và đọc dữ liệu để tạo ra một cá thể trả về theo dạng mẫu.
Kịch bản lệnh này trông giống như Liệt kê 11.
Listing 11. The convertGame.php script
<?php
$nextGame = rand(1, 10);
$lines = file('game'.$nextGame.'.sdk');
echo '<s:game xmlns:s="http://www.example.com/sudoku">';
foreach ($lines as $line_num => $line) {
$line = str_replace(" ", "", $line);
$line = str_replace("\n", "", $line);
if ($line_num > 0 && $line != '') {
echo "<s:row>";
for ($x = 0; $x < 9; $x++){
$thisBox = substr($line, $x, 1);
if ($thisBox == "0") {
echo "<s:box>.</s:box>";
} else {
echo "<s:box s:ro='yes'>".$thisBox."</s:box>";
}
}
echo "</s:row>";
}
}
echo " <s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:square><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box><s:box>.</s:box><s:box>.</s:box>
<s:box>.</s:box></s:square>
<s:submitButtonElement>Submit</s:submitButtonElement>
<s:correctRows>no</s:correctRows>";
echo '</s:game>';
?> |
Để bắt đầu, bạn cần chọn trò chơi tiếp theo. Tại đây, bạn sẽ chọn một số
nguyên ngẫu nhiên giữa 1 và 10 (gồm cả 10). Sau đó, bạn có thể sử dụng số
nguyên đó để tạo ra tên tệp trả về cho trò chơi này. Từ đó, bạn có thể sử
dụng hàm file() để trích xuất một mảng của từng
dòng trong tệp.
Sau đó, bạn có thể bắt đầu xuất ra cá thể, bắt đầu với thẻ mở cho phần tử
gốc, game. Với mỗi dòng, đầu tiên trích xuất
tất cả các khoảng trống và báo hiệu xuống dòng ở cuối dòng. Một khi bạn đã
làm xong, bạn có thể nói ra sự khác biệt giữa các dòng thực sự chứa dữ
liệu và các dòng không chứa dữ liệu. Với mỗi dòng có chứa dữ liệu, bạn mở
một phần tử row mới và tạo vòng lặp qua mỗi chữ
số để tạo ra một phần tử box. Nếu chữ số đó là
số không (0), bạn thay thế nó bằng một dấu chấm, nhưng nếu nó khác không,
bạn cũng bao gồm thuộc tính chỉ đọc (ro) cho
nó. Ở cuối mỗi dòng, bạn đóng phần tử row
lại.
Một khi bạn đã giải quyết dữ liệu trong tệp trò chơi, bạn cần dữ liệu bổ
sung, ví dụ như các phần tử square và các phần
tử submitButtonElement và
correctRows. Cuối cùng, đóng phần tử
game lại.
Nếu bạn tải biểu mẫu, lược đồ, và kịch bản lệnh convertGame.php lên máy chủ
và gọi trò chơi trong trình duyệt, bạn có thể kiểm tra trò chơi. (Để tránh
phải giải quyết từng trò chơi câu đố trước khi trình lên, hãy đưa ra nhận
xét về phần tử bind ẩn dấu nút Submit). Nhấn
nút Submit nhiều lần để thấy sự thay đổi trò chơi câu đố đó.
Đó chính là trò chơi!
Trong loạt hai bài viết này, bạn đã tạo ra một biểu mẫu XForms mô phỏng một trò chơi Sudoku. Trong Phần 1, bạn tạo ra biểu mẫu cơ bản, cho phép người chơi chơi trò này bằng cách sử dụng các trình đơn thả xuống. Biểu mẫu này tính toán xem trò chơi câu đố này đã được giải hay chưa và phản ứng sao cho phù hợp. Trong Phần 2, bạn đã thay đổi biểu mẫu để sử dụng các đầu vào văn bản, thêm các ràng buộc lược đồ để chắc chắn rằng người chơi không thể nhập vào dữ liệu không hợp lệ. Bạn cũng đã cung cấp cho người chơi khả năng lưu một trò chơi hiện cục bộ, và tải trò chơi đã lưu trở lại vào trong cá thể hiện tại. Cuối cùng, bạn xem xét một cách để tạo ra các trò chơi mới và cung cấp chúng theo biểu mẫu.
| Mô tả | Tên | Kích thước | Phương thức tải |
|---|---|---|---|
| Part 2 sample code | xforms2_source.zip | 7KB | HTTP |
Học tập
-
Sudoku.com đưa ra những lời khuyên
cho những người mới bắt đầu chỉ học cách chơi trò chơi này, trong khi
Michael Mepham, người cung cấp các trò chơi câu đố cho tờ Daily Telegraph
và Los Angeles Times http://www.sudoku.org.uk đưa ra phân tích để giải các trò chơi
câu đố đầy thử thách này. WebSudoku có các trò chơi câu đố rất khó để bạn có thể chơi trực
tuyến.
- Hãy nhận một hướng dẫn cơ bản cho XForms trong Giới thiệu về XForms, Phần 1: Chuẩn Web mới cho các biểu
mẫu (developerWorks, 09.2006).
- Tìm hiểu thêm về XForms trong Vùng XML của IBM
developerWorks.
- Tìm hiểu thêm về sự kiện trình lên XForms
trong Lời khuyên XForms: Sử dụng các sự kiện trình lên biểu mẫu
(developerWorks, 11.2006).
- Tìm hiểu cách chấp nhận dữ liệu XForms
trong Java (developerWorks, 10.2006), Perl (developerWorks, 10.2006), và PHP (developerWorks, 10.2006).
-
Chứng chỉ
XML của IBM: Tìm cách bạn có thể trở thành một nhà phát triển có
chứng chỉ IBM về XML và các công nghệ liên quan.
-
Thư viện
kỹ thuật XML: Xem Vùng XML của developerWorks với một vùng rộng
lớn các bài viết kỹ thuật và các lời khuyên, các hướng dẫn, các tiêu
chuẩn, và các sách Đỏ của IBM.
-
Các sự kiện kỹ thuật và Webcast của developerWorks: Theo sát với
công nghệ trong các phiên này.
- Truy cập XForms.org, một ngân hàng thông tin liên quan đến
XForms.
- Hãy nghe tác giả bàn về nỗi ám ảnh của
mình với Sudoku trong podcast của developerWorks này.
Lấy sản phẩm và công nghệ
-
Python Sudoku
vừa tạo ra và vừa giải các trò chơi câu đố Sudoku.
-
Khuyến nghị XForms được W3C ủng
hộ.
- Để biết thêm
thông tin về XPath, hãy đọc Khuyến
nghị XPath.
- Nhận MozzIE, một hướng
dẫn mã nguồn mở cho phép bạn đưa XForms vào trong Internet Explorer.
Thảo luận
- Các blog
developerWorks: Dành thời gian cho công đồng
developerWorks.
Nicholas Chase đã phát triển trang web cho các công ty lớn như Lucent Technologies, Sun Microsystems, Oracle, và Tampa Bay Buccaneers. Nick đã từng là một giáo viên vật lý ở trường phổ thông, một nhà quản lý thiết bị phóng xạ mức thấp, một nhà biên tập tạp chí khoa học viễn tưởng trực tuyến, một kỹ sư đa phương tiện, một hướng dẫn của Oracle, và một trưởng phòng công nghệ của một công ty tương tác truyền thông. Nick là tác giả của một số sách