Trò chơi úp bài Cho M quân bài mang các số từ 1 đến M ( M<=12 ) , các quân bài đang lật ngửa .Cho một số nguyên dơng N ( N<=200 ) . Trò chơi nh sau : Hai ngời lần lợt thay nhau úp quân bài theo qui tắc : + Cộng giá trị quân bài vào tổng điểm , nếu tổng điểm bằng N thì ngời đó thắng + Khi úp một quân bài (ngửa ) thì đồng thời lật ngửa lại quân bài đang bị úp tr ớc đó. Hãy lập trình theo yêu cầu : 1) Nhậptừ bàn phím số N,M. 2) Bốc thăm ai đi trớc 3) Thể hiện trò chơi trên màn hình trò chơi giữa ngời và máy sao cho khả năng thắng của máy có thuận lợi hơn Thuật toán : Giả sử N=10 , M=3 . Trớc hết lập bảng phơng án sau : 1 2 3 4 5 6 7 8 9 10 1 1 0 0 1 1 0 0 1 1 0 2 0 0 0 1 0 0 0 1 0 0 3 0 0 1 1 0 0 1 0 0 0 Nếu máy đi trớc : Chọn quân số 1 ( vì A[1,1] = 1 ) , dồn ngời chơi phải chọn quân 2 hoặc 3 , do đó cột điểm tiếp theo là 1+2 =3 hoặc 1+3=4 . Trong các cột điểm 3 và 4 , đến lợt máy đi lại có số 1 , nên máy lại đợc chọn quân ở hàng nào đó có số 1 . . . Quá trình cứ nh thế , cho đến khi sẽ dẫn tới tình trạng : sau khi ngời đi quân số 2 hoặc 3 thì tổng điểm là 9 đến lợt máy đi , máy úp quân số 1 , đợc tổng điểm là 10 . Máy thắng . Nếu máy đi sau : Rất có thể máy bị dồn vào tình trạng : nhận cột điểm không có số 1 . Khi đó máy phải úp quân nào đó để cột điểm mới có ít số 1 nhất , nghĩa là tạo ra tình thế bất lợi nhất cho ngời ( Máy hy vọng ngời chơi này này không biết qui luật , úp phải quân bài ở hàng 0 của cột điểm mới này) Vấn đề còn lại các em sẽ thắc mắc là : Làm thế nào có bảng phơng án nh vậy ? Lý do đơn giản là chúng ta lần ngợc từ trạng thái kết thúc chắc thắng về trạng thái đầu . Cụ thể + Gán A[1,N-1] = 1 + Sau đó xây dựng dần các số 1 ở các cột điểm đ = N-2,N-3, ,1 theo qui tắc : Chọn số quân lần lợt là Sq = 1 M . Gọi số lợng số 1 ở cột đ+Sq là x ( với điều kiện x<=N ) . Nếu x=0 hoặc ( x=1 và A[Sq,x]=1 ) thì A[Sq,đ]=1 ; còn lại A[Sq,đ]=0 Chơng trình Uses Crt; Type pt = 0 1; Var Diem,sq,m,n,Luu : Byte; S : String; A : Array[1 12,0 200] of 0 1; Ch : Char; Ok : Boolean; Procedure Ve(i,j : Byte;Ch : Char); Var k,h : Byte; Begin Textcolor(7); If j<>0 then For k:=i to i+4 do For h := j to j+4 do Begin Gotoxy(h,k); Write(ch); End; Textcolor(14); End; Procedure Nhap; Begin Repeat Clrscr; Write('So diem toi da ( N<= 200), N = '); {$I-} Readln(N); {$I+} Until (Ioresult=0) and (N in [1 200]); Repeat Gotoxy(1,2); Write('So quan bai ( M<=12 ) , M = '); {$I-} Readln(M); {$I+} Until (Ioresult=0) and (M in [1 12]); End; Function Sl_dau(diem : Byte) : Byte; Var d,j : Byte; Begin d := 0; For j:=1 to M do If A[j,diem]=1 then Inc(d); SL_dau := d; End; Function Thang(i,t : Byte) : pt; Var j,p : Byte; Begin p := SL_dau(i+t); If p>1 then Thang := 0 Else If p=0 then Thang := 1 Else If p=1 then Begin If A[t,i+t]=1 then Thang := 1 Else Thang := 0; End; End; Procedure Taobang; Var i,j : Byte; Begin For sq:=1 to M do Begin Ve(5,sq*6,char(219)); Gotoxy(sq*6+2,10); Write(sq); End; FillChar(A,Sizeof(A),0); A[1,N-1] := 1; For j:=N-2 downto 0 do For i:=1 to M do If (i+j<=N) and (Thang(j,i)=1) then A[i,j] := 1; {A[1,1] := 0;} Diem := 0; Luu := 0; End; Procedure Boctham; Begin Gotoxy(20,16); Write('Ban chon di truoc hay di sau (T/S) ? '); Repeat Ch := Upcase(Readkey); Until Ch in ['T','S']; Gotoxy(20,16); Clreol; End; Procedure GhiMaydi(sqm,diem : Byte); Begin Gotoxy(50,16); Write('May up quan bai so ',sqm:3); Gotoxy(20,18); Textcolor(12); Write('Tong so diem ',diem:6); Textcolor(14); End; Procedure May_choi; Var k,x : Byte; Begin { Tinh huong tot } For k:=1 to M do If (k<>Luu) and (A[k,diem]=1) then Begin Ve(5,luu*6,char(219));{Lat bai cua nguoi} Luu := k; Ve(5,luu*6,char(176));{May up quan moi } Inc(diem,k); Ghimaydi(k,diem); Exit; End; { Tinh huong xau : chon cot co it hang co dau } { de hy vong nguoi kia boc dung hang khong dau } x := M; For k:=1 to M do If k<>Luu then If (SL_dau(k+diem)<x) then x := k; Ve(5,luu*6,char(219)); { Lat bai cua nguoi } Luu := x; Ve(5,luu*6,char(176));{ May up quan bai moi } Inc(diem,x); Ghimaydi(x,diem); End; Procedure Nguoidi; Var Ch : Char; Begin Gotoxy(1,24); Write('Ban chon quan bai bang cach chuyen mui ten ',char(24)); Repeat Gotoxy(sq*6+2,11); Writeln(char(24));{Viet mui ten len } Ch := Upcase(Readkey); Gotoxy(sq*6+2,11); Write(chr(32)); {Xoa mui ten len } Case ch of 'K' : If sq>1 then Dec(sq) Else sq := m; 'M' : If sq<m then Inc(sq) Else sq := 1; End; Until (sq<>Luu) and (Ch=#13); Gotoxy(1,16);Write(' '); Gotoxy(1,16); Write('Ban vua up quan = ',sq); Inc(diem,sq); If Luu>0 then Ve(5,luu*6,char(219)); Luu := sq; Ve(5,luu*6,char(176)); Delay(1000); End; BEGIN Textcolor(14); TextBackGround(1); Repeat Nhap; Taobang; Boctham; If ch='T' then nguoidi; Ok := False; If diem<=N then Repeat May_choi; If Diem<=N then Nguoidi Else Ok := True; Until Diem>N; Clrscr; Gotoxy(20,20); If Ok then Writeln('Ban thang ! ') Else Writeln('May thang ! '); Gotoxy(40,20); Write('ESC to quit '); Until Readkey=#27; END.