Thứ Tư, 14 tháng 8, 2013

AI tự động giải quyết vấn đề.

thật ra không có gì thông minh cho lắm, người lập trình nghĩ sao viết vậy thì các nhân vật tự động cũng làm theo như vậy. nhưng cũng có những Artificial inteligence thật sự làm người ta ngạc nhiên, điều đó phụ thuộc vào người lập trình như thế nào, có khi họ không phải là người truyền cách thức hoạt động vào code mà là một người khác có trí tuệ cao hơn họ, người này có thể không biết gì về lập trình cả.
Ở đây tôi chỉ làm cho xe của địch có khả năng tự di chuyển và nả đạn khi cần thiết, như vậy thì mới thật sự là một trò chơi. trong game.java tôi thêm một hàm mới, hàm này tổng hợp một mã phím theo thời gian.

//game.java

import javax.microedition.lcdui.*;
import java.util.*;

public class game extends Canvas {
String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0,k,ak;
Midlet m;
Font f=Font.getDefaultFont();
T t,x;
long lai=0;

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0);
x=new T(w-16*3,h-16*3,0x6060f0);}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index

g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
 if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
t.paint(g, k);
x.paint(g, (ak=ai(x,ak)));
if(check(t,x)){x.color-=0x000010;}
if(check(x,t))t.color-=0x100000;
break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

protected void keyReleased(int k){this.k=0;}

public void keyPressed(int k){
this.k=k;
//cho di chuyển vị trí thanh menu
if(mode==0){
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0)mindex=smenu.length-1;
 if(mindex==smenu.length)mindex=0;
//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;
//các lệnh cho menu góc màn hình
if(k==-6)m.notifyDestroyed();}
if(k==-7)mode=0;}

boolean check(T a, T b){
int xc=(a.d.x-b.x)/16/3;
int yc=(a.d.y-b.y)/16/3;
if(xc==0&amp;&amp;yc==0&amp;&amp;a.d.f!=-1){return true;}
return false;}



//đây là hàm tổng hợp theo thời gian mã key cho xe tự động

int ai(T a,int ak){
Random rd=new Random(); 
// điều kiệm để đổi hướng xe là sau 2 giây (2000millis giây)
if(lai<System.currentTimeMillis()-2000){
 lai=System.currentTimeMillis();
    int k=Math.abs(rd.nextInt())%4;
return -(k+1);}

//nếu như không có gì thay đổi thì cứ sau 25 millis giây cho tiến về trước 1 bước
if(System.currentTimeMillis()%25==0)
  return -(1+a.f);

//nếu không thì trả về key không, tức không di chuyển
return 0;}

}



. Kết quả của ta sẽ là xe tự động di chuyển
Và sửa lại một chút cho khả năng tự nhả đạn:
int ai(T a,int ak){
Random rd=new Random();

if(lai<System.currentTimeMillis()-2000){
 lai=System.currentTimeMillis();
int k=Math.abs(rd.nextInt())%4;
return -(k+1);}
if(System.currentTimeMillis()%25==0)
  return -(1+a.f);
if(rd.nextInt()%3==0&amp;&amp;a.d.f==-1){return -5;}
return 0;}

trúng đạn

bây giờ tôi sẽ thêm một hàm vào trong game.java để phát hiện xem khi nào thì xe ta bị trúng đạn hoặc là xe địch bị ta bắn trúng.

//game.java

import javax.microedition.lcdui.*;

public class game extends Canvas {
String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0,k;
Midlet m;
Font f=Font.getDefaultFont();
T t,x;


public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0);
x=new T(w-16*3,h-16*3,0x6060f0);}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index
g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
t.paint(g, k);
x.paint(g, 0);

//nếu như là kiểm tra thấy đạn của xe này chạm xe kia thì cho xe kia bị đổi màu, tức nhiên là trong thực tế bạn có thể cho nó biến mất

if(check(t,x)){x.color-=0x000010;}
if(check(x,t)){t.color-=0x100000;}

break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

protected void keyReleased(int k){this.k=0;}

public void keyPressed(int k){
this.k=k;
//cho di chuyển vị trí thanh menu
if(mode==0){
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0)mindex=smenu.length-1;
if(mindex==smenu.length)mindex=0;
//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;
//các lệnh cho menu góc màn hình
if(k==-6)m.notifyDestroyed();}
if(k==-7)mode=0;}


 //hàm check này nhận giá trị là 2 kiểu T và sau đó kiểm tra xem tọa độ đạn của xe đầu và tọa độ của xe sau nếu như mà chạm nhau thì trả lại giá trị true, tương đương với nghĩa là đã bắn trúng.
boolean check(T a, T b){
int xc=(a.d.x-b.x)/16/3;
int yc=(a.d.y-b.y)/16/3;
if(xc==0&&yc==0&&a.d.f!=-1){return true;}
return false;}

}

* kết quả như sau, sau khi trúng đạn xe địch thay đổi màu:

chuẩn bị các nguyên liệu cho game

trong game có các thành phần như là nhân vật, chướng ngại vật, kẻ thù, và những vật dụng khác cũng như ngoại cảnh. tùy theo ý thích của mỗi người mà chúng ta có thể chuẩn bị đủ mọi thứ. cũng như việc lắp ráp một chiếc xe cần phải có những thứ tạo nên chiếc xe đó như khung xe, bánh xe, dây xích, bulong, ốc vít....
bây giờ tôi sẽ làm một game đơn giản thôi và sẽ sử dụng hoàn toàn bằng lệnh, tức là không dung thêm bất cứ file nào ngoài code java. game mà tôi sắp viết nên đây là một trò bắn tăng cổ điển, giống như trò chơi trên các máy bấm hộp nhỏ nhỏ xài pin mà ngoài chợ thường bán.
. Ta cần các hình sau:
- xe tăng của ta gọi là T
- xe tăng chướng vật gọi là X
- đạn bắn ra gọi là F
mỗi một hình như vậy chúng ta sẽ tạo trên một class riêng và chúng phải có những thuộc tính sau:
- tọa độ x
- tọa độ y
1. đầu tiên tôi viết class vẽ T, như sau:
import javax.microedition.lcdui.*;

public class T {

//T này ngoài tọa độ x,y còn có thêm biến frame, và biến màu sắc
int x,y,f,color;

//biến lm ghi lại lần di chuyển cuối cùng của T
long lm=0;

//biến shape là các frame của T, gồm có 4 frame
byte[][] shape={{0,1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1,0},{0,1,1,1,1,0,0,1,1},{1,1,0,0,1,1,1,1,0}};

//hàm khởi tạo nhận giá trị tọa độ ban đầu và màu sắc của T
public T(int x,int y,int color){
this.x=x;
this.y=y;
this.color=color;}

//hàm paint dùng để nhận biến Graphics và vẽ trên đó, cùng với biến k là phím nhấn trên bàn phím
public void paint(Graphics g,int k){

//check xem lần cuối cùng di chuyển và khoảng thời gian hiện tại có cách nhau 60 millis giây
if(lm<System.currentTimeMillis()-60){
switch(k){
case -1: f=0; y-=16; break;
case -2: f=1; y+=16; break;
case -3: f=2; x-=16; break;
case -4: f=3; x+=16; break;}
lm=System.currentTimeMillis();}

//đặt màu cho xe tăng này
g.setColor(color);

//vẽ xe tăng theo frame, nếu là 0 thì không vẽ ra được gì, nếu 1 thì vẽ 1 ô vuông, tạo nên hình chiếc xe
for(int i=0;i<shape[f].length;i++){
int c=i%3,r=(i-c)/3;
g.fillRect(x+c*16,y+r*16,16*shape[f][i],16*shape[f][i]);}
}
}

kết quả của ta sẽ như thế này. ta không cần phải thiết kế thêm class X nữa mà chúng ta dùng class T để tạo luôn xe tăng chướng ngại, chỉ cần đổi màu một chút là được, và kết quả ta được như sau:


Tất nhiên trong file game.java chúng ta cũng phải thay đổi một chút để đưa hai đối tượng T này vào:

import javax.microedition.lcdui.*;

public class game extends Canvas {
String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0,k;
Midlet m;
Font f=Font.getDefaultFont();
T t,x;

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();
t=new T(0,0,0xf0f0f0);
x=new T(w-16*3,h-16*3,0x6060f0);}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index
g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
t.paint(g, k);
x.paint(g, k);
break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

protected void keyReleased(int k){this.k=0;}

public void keyPressed(int k){
this.k=k;
//cho di chuyển vị trí thanh menu
if(mode==0){
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0 )mindex=smenu.length-1;
if(mindex==smenu.length)mindex=0;

//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;
//các lệnh cho menu góc màn hình
if(k==-6)m.notifyDestroyed();}
if(k==-7)mode=0;}
}

. Bây giờ thì viết thêm class F nữa, đây sẽ là đạn bắn ra từ các xe.
//F.java
import javax.microedition.lcdui.*;
public class F {
int x,y,color,f=-1,speed;
long lm=0;
public F(int x,int y,int color,int speed){
this.x=x;
this.y=y;
this.color=color;
this.speed=speed;}
public void fire(Graphics g,int x,int y){
if(f==-1){this.x=x; this.y=y;}
g.setColor(color);
if(System.currentTimeMillis()%500<250)
g.fillRect(this.x,this.y,16,16);

if(f!=-1&amp;&amp;lm<System.currentTimeMillis()-speed){
switch(f){
case 0: this.y-=16; break;
case 1: this.y+=16; break;
case 2: this.x-=16; break;
case 3: this.x+=16; break;}
lm=System.currentTimeMillis();}
if(f!=-1&amp;&amp;(Math.abs(this.x-x)&gt;240||Math.abs(this.y-y)&gt;320)){f=-1;}
}
}

. cuối cùng thì mỗi xe đều có khả năng nhả đạn, nên trong T class ta chỉnh sửa lại một chút để tạo khả năng bắn đạn cho các xe này.
//T.java
import javax.microedition.lcdui.*;

public class T {
F d;
int x,y,f,color;
long lm=0;
byte[][] shape={{0,1,0,1,1,1,1,0,1},{1,0,1,1,1,1,0,1,0},{0,1,1,1,1,0,0,1,1},{1,1,0,0,1,1,1,1,0}};
public T(int x,int y,int color){
this.x=x;
this.y=y;
this.color=color;
d=new F(x+16,y+16,0xf00000,500);}
boolean check(){return (lm<System.currentTimeMillis()-60);}

public void paint(Graphics g,int k){
switch(k){
case -1: f=0; if(check()){y-=16; lm=System.currentTimeMillis();} break;
case -2: f=1; if(check()){y+=16; lm=System.currentTimeMillis();} break;
case -3: f=2; if(check()){x-=16; lm=System.currentTimeMillis();} break;
case -4: f=3; if(check()){x+=16; lm=System.currentTimeMillis();}break;
case -5: d.f=this.f; break;}
g.setColor(color);
for(int i=0;i<shape[f].length;i++){
int c=i%3,r=(i-c)/3;
g.fillRect(x+c*16,y+r*16,16*shape[f][i],16*shape[f][i]);}
d.fire(g,x+16,y+16);
}
}

kết quả ta được như thế này.

chia các phần trong một trò chơi


hãy tưởng tượng, khi mở một trò chơi ra bạn sẽ có thể gặp một phần giới thiệu trước, sau đó là menu, mỗi một lựa chọn trong menu lại đưa ra một màn hình khác nhau, như màn chơi, phần hướng dẫn, phần tóm tắt...
bài này sẽ tạo ra một class hiển thị các phần như vậy, và menu của chúng ta chỉ có 3 mục: play game, help, about, với một nút exit ở dưới trái màn hình.
file Midlet của chúng ta sẽ chỉ có thêm một dòng so với ban đầu:
//Midlet.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;


public class Midlet extends MIDlet {
public void startApp() {
Display.getDisplay(this).setCurrent(new game(this));
}

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}
}
tạo một class mới đặt tên là game, có nội dung như sau:
//game.java

import javax.microedition.lcdui.*;
public class game extends Canvas {

String[] smenu={"play game","help","about"};
int w,h,fh,mindex=0,mode=0;
Midlet m;
Font f=Font.getDefaultFont();

public game(Midlet m){
this.m=m;
setFullScreenMode(true);
w=getWidth();
h=getHeight();
fh=f.getHeight();}

public void paint(Graphics g){
g.setColor(0);
g.fillRect(0, 0, w, h);
g.setColor(0xf0f0f0);
switch(mode){
case 0: //vẽ menu
//vẽ thanh index
g.fillRect(0, (h-fh*3)/2+mindex*fh, w, fh);
//vẽ các menu
for(int i=0;i<smenu.length;i++){
if(i==mindex){g.setColor(0);}else{g.setColor(0xf0f0f0);}
g.drawString(smenu[i],w/2 ,( h-fh*3)/2+i*fh, Graphics.HCENTER|Graphics.TOP);
}
break;
case 1: //vẽ game play
g.drawString(smenu[0], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 2: //vẽ help
g.drawString(smenu[1], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;
case 3: //vẽ about
g.drawString(smenu[2], w/2, h/2, Graphics.BASELINE|Graphics.HCENTER);
break;}
//vẽ nút lệnh
g.setColor(0xf0f0f0);
g.drawString("exit", 0, h, Graphics.LEFT|Graphics.BOTTOM);
g.drawString("back", w, h, Graphics.RIGHT|Graphics.BOTTOM);
repaint();}

public void keyPressed(int k){

//cho di chuyển vị trí thanh menu
if(k==-1)mindex--;
if(k==-2)mindex++;
if(mindex<0) mindex=smenu.length-1;
if(mindex==smenu.length) mindex=0;

//thay đổi mode khi lựa chọn menu
if(k==-5)mode=mindex+1;

//các lệnh cho menu góc màn hình
if(k==-7)mode=0;
if(k==-6)m.notifyDestroyed();}
}

công cụ sử dụng trong bài viết

Sau đây là chia sẻ của tôi về những hiểu biết về n.n java đã tích góp đc. trong thời gian  qua post lên đây để có dịp se đọc lại và cho các bạn tham khảo
. đối với người dùng windows thì netbean hay java wireless toolkit là những phần mềm hỗ trợ lập trình J2ME tốt nhất. ngoài ra các bạn còn cần phải tải gói java hỗ trợ là jdk.
. để tiện lợi, tôi sẽ sử dụng netbean để tiến hành hướng dẫn trong những bài viết này, giao diện và các phần bổ trợ gần như đầy đủ.
netbean download vào trang download và chn download gói all (240Mb)
jdk gói java bổ trợ cung cấp thư viện và môi trường chạy giả lập
. Bạn cài gói JDK trước sau đó cài netBean sau, quá trình khởi động đầu tiên NetBean sẽ kiểm tra phần cứng và cấu hình hơi lâu một chút.
. để tạo một Project mới bạn bấm vào File -> new Project -> (cataloge) Java ME -> (Project) Mobile Application. sau đó nhấn Next
- tiếp theo đặt tên cho Project, bỏ chọn create Hello Midlet, bấm finish
- ở khung bên trái dưới tên project, chọn source package, click phải vào và chọn new -> Midlet, bấm finish, đây là main class của chúng ta.
- để tạo thêm những class phụ chúng ta cũng bấm phải vào source package và chọn new -> class, đặt tên và nhấn finish.
- để mở một file source chỉ cần nhấp đúp vào tên của nó bên khung bên trái.

Đôi khi tôi cảm thấy trống rỗng

không còn như ngày xưa nữa, khi tôi không có chút vướng bận gì. bây giờ thì đã khác, có những thứ tôi muốn làm nhưng lại không làm được. tôi thấy ở đó gần ngay trước mặt mình nhưng lại không làm sao tiến gần lại được. nhiều khi cơ hội không bao giờ đến lần thứ 2, tôi không có ý định gì hết, tôi cũng không biết những ý định của người khác. khi họ tiến tới gần tôi và nói vài thứ, tôi tin vài thứ. có thể ngoài những gì biểu hiện ra bên ngoài còn có những thứ ờ bên trong nữa mà tôi không biết được. dù sao thì tôi cũng có những thứ làm mình cảm thấy dễ chịu, từ bây giờ đến khi kết thúc.
vài ngày trước tôi còn như đang ở một nơi ấm áp dù bên ngoài trời đang mưa, tôi cũng quan tâm xem cái cảm giác của mình là có thật hay không. tôi biết, nó không thật sự là như vậy, tôi cũng không biết nữa. hôm nay tôi lại cảm thấy muốn nói ra điều gì đó, nhưng như thường lệ, chẳng bao giờ tôi nói ra gì cả, những gì mà tôi muốn nói, thật sự là muốn hỏi xem nó có thật sự là như vậy không thôi, thật sự là một câu trả lời.
khó quá bây giờ thì người biết tất cả mọi thứ không còn ở bên tôi nữa rồi, và mọi thứ làm tôi cứ tự hỏi mãi, liệu một ngày nào đó tôi sẽ thật sự biết được nó chứ. ngày mai, không phải là kết thúc…

[phim] proposal

Tải phim
chuyện này thật là điên rồ, tôi không muốn lừa dối mọi người nữa, thật sự đây không phải là tình yêu thật sự…”
đứng bên bờ vực bị đuổi về canada, sếp nữ này phải làm sao đây. điều cô ta có thề làm là lấy một chàng trai để có thể ở lại đây, và cô gái đã thực hiện một hợp đồng với cấp dưới của mình rằng: nếu lấy cô thì cô sẽ chiếu cố cho những bài viết của anh. tất nhiên chàng trai không hề chịu nhận lời một cách dễ dàng như vậy, chàng trai bắt cô phải quì gối giữa đường để cầu hôn anh và sau đó là một chuyến du lịch trở về nhà anh để nói với những người trong gia đính.
có lẽ đối với em thì đây chỉ là một hợp đồng, nhưng đối vói anh nó thật sự là điều mà anh muốn thực hiện, chỉ tại em quá cứng nhắc và có điều gì đó giống như anh sợ rằng em sẽ từ chối anh…”
không ai ngờ tới việc thay đổi ý kiến của cô gái khi cô tiếp xúc với những người trong gia đình, đó thật sự là một gia đình với những người tốt và cô không có quyền lừa dối họ, không có quyền cướp đi người con người cháu yêu quí của họ, chỉ vì cô phải chấp nhận sự thật của bản thân mình là cô đã yêu thật sự….
phim vui không thể nói, tất cả mọi người đều cảm thấy dễ chịu, tất nhiên đó chỉ là những chuyện trên phim ảnh, với phim ảnh, ta có thề làm mọi chuyện…