Hướng dẫn tự in tên trên lon Coca-Cola không dùng Photoshop

Người đăng: share-nhungdieuhay on Thứ Năm, 10 tháng 7, 2014






Trào lưu săn lùng tên mình trên lon Coca-Cola đang làm mưa làm gió tại Việt Nam và đây cũng là trào lưu của hơn 100 quốc gia trước khi nó xuất hiện tại Việt Nam. Chiến dịch quảng cáo của Coca-Cola được cho là sáng tạo và thành công nhất trong lịch sử của hãng nước giải khát này.
Tuy nhiên, không phải cái tên nào cũng được xuất hiện trên lon Coca-Cola. Hiện nay, ở Việt Nam đã có 30 cái tên phổ biến và 20 cá tính khác nhau được in nhưng như thế vẫn chưa thể thỏa mãn tất cả.
Nhằm thỏa mãn nhu cầu của những bạn trẻ chỉ muốn có tên trên lon Coca-Cola để đăng lên Facebook cho vui, ICTnews sẽ hướng dẫn một số công cụ để tạo ảnh “giả” đơn giản, trực tiếp trên web (hãy luôn đề phòng nguy cơ có virus). Mỗi công cụ có các kiểu mẫu ảnh khác nhau nên ICTnews sẽ làm thử để cho các bạn tham khảo.
Địa chỉ 1
Bước 1: Bạn truy cập vào địa chỉ “ob.upfile.vn/coke/index.php”.
A1-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Truy cập vào địa chỉ “ob.upfile.vn/coke/index.php” sẽ có giao diện như trong hình.
Trong hình trên, ô số 1 là nơi nhập cái tên bạn muốn xuất hiện trên lon Coca-Cola.
Ô số 2 là nơi bạn chọn kiểu ảnh chụp lon Coca-Cola.
Số 3 là nơi bạn lựa chọn hiện hay ẩn quảng cáo. Hãy chuyển sang trạng thái Ẩn để tác phẩm của mình trông thật hơn.
Số 4 là nơi bạn nhập mã bảo vệ hiển thị phía trên.
Số 5 là nút bấm để thực hiện quá trình in.
Bước 2: Sau khi điền toàn bộ thông tin cần thiết và bấm nút thực hiện, bạn sẽ được tác phẩm như dưới đây:
A3-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Sau khi điền toàn bộ thông tin cần thiết và bấm nút thực hiện, bạn sẽ được tác phẩm như trong hình (kiểu lon nằm).
Bước 3: Để lưu về máy, bạn không nên click vào đường dẫn Bấm vào ảnh để tải xuống vì hình ảnh bạn tải về theo cách này sẽ ở định dạng không thể hiển thị.
Bạn nên click chuột phải vào hình ảnh, chọn chế độ Save Image As như dưới đây:
A2-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Để lưu về máy, bạn nên click chuột phải vào hình ảnh và chọn chế độ Save Image As.
Dưới đây là những kiểu mẫu in trên lon Coca-Cola khác để bạn tham khảo:
A4,5-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Kiểu lon đứng.
A5-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Kiểu có tay cầm.
A6-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Kiểu dành cho cặp đôi.
A7,5-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Kiểu… Bùi Bích Phương.
A8-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Một kiểu lon nằm khác.
A9-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Kiểu lon bia Heineken.
Địa chỉ 2
Bước 1: Hãy vào địa chỉ “bam.vn/coca”, bạn sẽ gặp giao diện như hình dưới đây:
B1-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Hãy vào địa chỉ “bam.vn/coca”, bạn sẽ gặp giao diện như trong hình.
Trong hình trên, ô số 1 là nơi bạn nhập tên muốn in.
Số 2 là nơi chọn kiểu ảnh chụp.
Số 3 là nút bấm để hoàn tất.
Bước 2: Sau khi điền toàn bộ thông tin cần thiết và bấm nút hoàn tất, bạn sẽ có thành quả. Địa chỉ này cung cấp cho bạn 1 kiểu ảnh mới (Lon Ngang Kiểu 2). Để lưu về máy hãy dùng cách chuột phải và Save Image As như thông thường.
B3-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Sau khi điền toàn bộ thông tin cần thiết và bấm nút hoàn tất, bạn sẽ có thành quả. Địa chỉ này có kiểu mới là Lon Ngang Kiểu 2.
Duy nhất chỉ một điều lưu ý là công cụ này không linh động cỡ chữ, vì vậy hãy dùng một cái tên dài vừa phải, nếu không tên của bạn sẽ bị tràn ra ngoài khuôn lon Coca-Cola.
B4,5-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Hãy dùng một cái tên dài vừa phải, nếu không tên của bạn sẽ bị tràn ra ngoài khuôn lon Coca-Cola.
Địa chỉ 3
Bước 1: Hãy vào địa chỉ “ylinkee.com/game/151”, bạn sẽ thấy giao diện như hình dưới đây:
C1-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Hãy vào địa chỉ “ylinkee.com/game/151”, bạn sẽ thấy giao diện như trong hình.
Trong hình trên, nút số 1 là nơi bạn chọn ẩn hay hiện bảng điều khiển.
Số 2 là nơi bạn chọn kiểu ảnh (kiểu 2 Lon là kiểu mới so với các địa chỉ trên).
Ô số 3 là nơi bạn nhập tên muốn in.
Ô số 4 là nơi để bạn nhập miêu tả ảnh, dùng khi chia sẻ ngay lên mạng xã hội.
Nút số 5 là nơi bạn ấn để hoàn thành quá trình tạo ảnh.
Bước 2: Với công cụ này, cỡ chữ cũng không linh hoạt nên bạn nhớ lưu ý nhập tên dài vừa phải, tránh tràn khuôn lon Coca-Cola.
C4,5-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Bạn nhớ lưu ý nhập tên dài vừa phải, tránh tràn khuôn lon Coca-Cola như trong hình.
C5-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Thành quả hoàn hảo cho những lon Coca-Cola có in tên bạn.
Một lưu ý khác là việc lưu ảnh bằng chuột phải và Save Image As với công cụ này có thể không tác dụng. Phương án cuối cùng để lưu ảnh là ẩn đi bảng điều khiển và chụp màn hình (ấn Print Screen).
Địa chỉ phụ
Gọi đây là địa chỉ phụ  vì Coca-Cola chỉ tạo nên công cụ này  để chia sẻ những chai Coca-Cola có tên thực sự  được in ngoài thị trường. Mặc dù vậy, bạn vẫn có thể tận dụng công cụ này để tạo ra cho mình thêm nhiều kiểu ảnh “tự sướng” với Coca-Cola.
Bước 1: Hãy vào địa chỉ “shareacoke.com” và điền tên vào nhãn chai Coca-Cola.
D1-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Hãy vào địa chỉ “shareacoke.com” và điền tên vào nhãn chai Coca-Cola (vùng mũi tên).
Bước 2:  Sau khi điền tên xong, công cụ này sẽ có nút  MAKE MY BOTTLE. Nhưng bạn không ấn vào đó vì công cụ này sẽ không tìm ra tên của bạn trên những nhãn chai ngoài thị trường.
Việc của bạn là ấn tổ hợp phím Ctrl + “-” để thu gọn chai Coca-Cola vừa khít với màn hình. Sau đó bạn có thể chụp màn hình (phím Print Screen) để lưu ảnh.
D2-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: Hãy ấn tổ hợp phím Ctrl + “-” để thu gọn chai Coca-Cola vừa khít với màn hình, sau đó bạn có thể chụp màn hình .
Bước 3: Thưởng thức các kiểu chai Coca-Cola bắt mắt khác.
D3-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: In tên trên kiểu chai Coca-Cola dành cho người ăn kiêng, Diet Coke.
D4,5-Huong-dan-tu-in-ten-tren-lon-Coca-Cola.jpg
Hướng dẫn in tên trên lon Coca-Cola: In tên trên kiểu chai Coca-Cola Zero, loại calo thấp.
More about

Tự nhiên bức xúc với forum.gmstore.vn

Người đăng: share-nhungdieuhay on Chủ Nhật, 6 tháng 7, 2014

Hi mọi người!

Nay lang thang trên Face vào mấy page về cocos2d-x để tìm giải pháp cho việc áp body vào armature + spritesheet animation, thì tìm được trang này

forum.gmstore.vn

Lượn 1 vòng thì thấy liền mấy bài này

http://forum.gmstore.vn/index.php?threads/h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn-c%C3%A0i-%C4%91%E1%BA%B7t-b%E1%BA%A3n-3-0-cocos2d-x.192/

http://forum.gmstore.vn/index.php?threads/physics-c%C6%A1-b%E1%BA%A3n-trong-cocos2d-x-v3-0.255/

http://forum.gmstore.vn/index.php?threads/t%E1%BA%A1o-v%C3%A0-ch%E1%BA%A1y-th%E1%BB%AD-ch%C6%B0%C6%A1ng-tr%C3%ACnh-hello-world-kinh-%C4%91i%E1%BB%83n.195/

http://forum.gmstore.vn/index.php?threads/gi%E1%BB%9Bi-thi%E1%BB%87u-cocos2dx.21/

http://forum.gmstore.vn/index.php?threads/ph%C6%B0%C6%A1ng-ph%C3%A1p-h%E1%BB%8Dc-cocos2dx.22/


Copy y chang, chả sửa đổi gì, kể cả 1 hình ảnh

http://laptrinhgamecocos2dx.blogspot.com/2014/04/bai-3-huong-dan-cai-dat-cocos2d-x-v3-tren-win-dow.html

http://laptrinhgamecocos2dx.blogspot.com/2014/04/gioi-thieu-ve-cocos2d-x.html

http://laptrinhgamecocos2dx.blogspot.com/2014/04/bai-4-hello-word-bai-code-dau-tien.html

http://laptrinhgamecocos2dx.blogspot.com/2014/04/bai-6-ball-physics-co-ban-trong.html

http://laptrinhgamecocos2dx.blogspot.com/2014/04/phuong-phap-hoc-cocos2d-x-cua-toi.html

Tự nhiên thấy bức xúc kinh, giống như kiểu mình vừa viết được 1 tác phẩm hay thì có người khác nhảy vào nhận là tác giả. 1 bài blog chẳng thể so sánh được với 1 tác phẩm nào đó, nhưng cũng là thành quả của mình làm ra, có quyền bức xúc chứ. Giá mà bên đó đặt link về blog này, mình cũng chả bức xúc làm chi. Đằng này....

Đúng là ở Việt Nam này, thậm chí tất cả thế giới ảo này, việc copy paste là ko thể tránh khỏi, nhưng ít ra hãy thể hiện sự tôn trọng nhau một chút = 1 cái link. Blog này mình làm cũng ko phải mục đích SEO mà cần link, hay keyword làm gì, mặc dù mình đang làm SEOer, cứ để bài viết tự lên thôi. Đó là thể hiện sự tôn trọng công sức của người khác. Các bạn nếu ở trường hợp của mình chắc cũng vậy thôi.

Chẳng phải mình nhỏ nhen với mấy bài viết làm chi, cứ coi việc đó là "Share" miễn phí để phổ biến Cocos tới mọi người yêu làm game đi, như thế cũng là vui rồi. Nhưng vẫn thấy cay cay trong mũi.

Đã thế, lập thử 1 acc, vào comment nỗi bức xúc, 15 phút sau đã ban với lý do: "Thích thì ban". Haizz, Buồn cho cách hành xử của mấy bác Admin + Mod.

Mình viết 1 bài nhỏ này hơi phiền mọi người nếu có vào đọc thì thông cảm nhé. Chỉ là chút tình cảm cá nhân đối với 1 hành vi không đẹp thôi. Bạn nào có lòng muốn vào 4rum đó để phản ánh thì mình cảm ơn, nhưng các bạn không cần phải làm thế làm gì cho phí thời gian, dành thời gian nghiên cứu thêm kỹ năng làm game thì hay hơn. Nhỉ?

Nếu bác nào bên đó có ghé qua đọc bài này thì cứ vào cho ý kiến, để mình trút thêm nỗi bức xúc nhé, vẫn còn đây. Hừm!

P/S: Chắc cũng còn nhiều trang khác cũng copy paste ấy chứ, nhưng biết làm sao được. Việc mình mình làm thôi, việc người ta đi copy paste thì kệ người ta thôi. Ai cũng cần phải sống và làm việc mà. Tự làm cũng để sống, copy paste cũng để sống. Thôi thông cảm vậy!

Cám ơn vì đã đọc, hết cả bức xúc, chuyển sang buồn .....WC :-))

More about

Bài 27: Học làm game thứ 4 - Game đập chuột ( Part 2)

Người đăng: share-nhungdieuhay on Thứ Bảy, 5 tháng 7, 2014

Hi các bạn!

Mấy ngày xem bóng hoa mắt quá đi, cũng làm tí cá độ cho vui, rất may là chưa có cái gì ra đi cả hehe. Nay trở lại hoàn thành nốt phần 2 game đập chuột này nhé ( Máy tính vẫn còn mà ).

Nhiệm vụ chính trong phần 2 này bao gồm các công việc như sau:
+ Đập chuột.
+ Tính điểm + Game Over
+ Add âm thanh.
+ Làm một chút hiệu ứng animation.

Đi luôn nhé!

Bạn mở file HelloWorldScene.h ra, thêm vào đoạn code sau vào phần public

// Tạo 1 Animation với các thông số, Tên ảnh, thứ tự hình ảnh, số khung, trễ
Animation* createAnimation(string prefixName, int* pFramesOrder, int framesNum, float delay);
bool onTouchBegan(Touch *touch, Event *unused_event); // Sự kiện Touch
// Mở , khóa chế độ đập chuột
void unsetTappable(Object* pSender);
void setTappable(Object* pSender);

// Cười + Đánh chuột
Animation *laughAnim;
Animation *hitAnim;
// Label dùng để hiển thị điểm
LabelTTF *label;

// Điểm số
int score;
// Số chuột không bị đập để tính game over
int totalSpawns;
bool gameOver;

nhớ thêm using namespace std; ở đầu file nhé ( vì dùng string )

Tiếp theo mở file HelloWorldScene.cpp ra

Include thêm #include "SimpleAudioEngine.h", và using namespace std;

Trong hàm init() thêm vào đoạn code sau ( trước return true )

auto visibleSize = Director::getInstance()->getWinSize();
auto visibleOrigin = Director::getInstance()->getVisibleOrigin();

//Tạo Animation chuột cười + Hit lên đầu chuột
int laughAnimOrder[6] = { 1, 2, 3, 2, 3, 1 }; // thứ tự các hình ảnh duyệt trong spritesheet
laughAnim = this->createAnimation("mole_laugh", laughAnimOrder, 6, 0.1f);
int hitAnimOrder[6] = { 1, 2, 3, 4 }; // Tương tụ trên
hitAnim = this->createAnimation("mole_thump", hitAnimOrder, 4, 0.02f);
// Nạp vào bộ đệm animation và đặt tên
AnimationCache::getInstance()->addAnimation(laughAnim, "laughAnim");
AnimationCache::getInstance()->addAnimation(hitAnim, "hitAnim");

//Touch
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

//Tạo 1 Label hiển thị điểm số
float margin = 10;
label = LabelTTF::create("Score: 0", "fonts/Marker Felt.ttf", 14);
label->setAnchorPoint(Point(1, 0));
label->setPosition(visibleOrigin.x + visibleSize.width - margin, 
visibleOrigin.y + margin);
this->addChild(label, 10);

//Khởi tạo các giá trị : điểm, tổng số chuột, game over
gameOver = false;
totalSpawns = 0;
score = 0;

// Nạp trước Âm thanh, play nhạc nền
CocosDenshion::SimpleAudioEngine::getInstance()->preloadEffect("laugh.mp3");
CocosDenshion::SimpleAudioEngine::getInstance()->preloadEffect("ow.mp3");
CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("whack.mp3", true);

Hàm Touch

bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event)
{
// Lấy tọa độ điểm Touch
Point touchLocation = this->convertTouchToNodeSpace(touch);
// Duyệt vector molesVector
for (Sprite *mole : molesVector) 
{
if (0 == mole->getTag()) continue; // bỏ qua, do đã ko được phép đập
// Lấy đường bao của Sprite ( dạng Rectang ), nếu chứa điểm Touch - tức là đập trúng chuột thì
if ( mole->getBoundingBox().containsPoint(touchLocation) ) 
{
// Âm thanh
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("ow.mp3");
// Cộng điểm và gán tag - ko đập thêm được
mole->setTag(0);
score += 10;

mole->stopAllActions(); // Dừng tất cả Action
// Tạo hitAnimation từ Cache
Animate *hit = Animate::create(hitAnim);
// Thụt xuống + biến mất
MoveBy *moveDown = MoveBy::create(0.2f, Point(0, -mole->getContentSize().height));
EaseInOut *easeMoveDown = EaseInOut::create(moveDown, 3.0f);
// Thực hiện 2 Animation tuần tự, bị hit và thụt xuống
mole->runAction(Sequence::create(hit, easeMoveDown, NULL));
}
}

return true;
}


Hàm createAnimation

Animation* HelloWorld::createAnimation(string prefixName, 
  int* pFramesOrder, 
  int framesNum, 
  float delay)
{
// Hãy xem lại bài 19 về cách làm animation từ spritesheet, có 5 bước nhỏ như sau
Vector<SpriteFrame*> animFrames; //1
// Tạo frame
for (int i = 0; i < framesNum; i++) //2
{
char buffer[20] = { 0 }; //3
sprintf(buffer, "%d.png", pFramesOrder[i]); //3
string str = prefixName + buffer; //3 Chính là tên của ảnh trong spritesheet 
// tạo frame, add vào vector
auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(str); //4
animFrames.pushBack(frame); //4
}
// Trả về 1 animation
return Animation::createWithSpriteFrames(animFrames, delay); //5
}


Hàm tryPopMoles, sửa lại 1 chút, hàm này là hàm update Scene theo thời gian, mình sẽ làm các việc kiểm tra gameOver, tính điểm trong này, vì các sự kiện này luôn phụ thuộc thời gian mà.

void HelloWorld::tryPopMoles(float dt)
{

if (gameOver) return; // Game over rồi thì thôi

// Hiển thị điểm = Label, tất nhiên có cách hiển thị điểm = font, text, mình ko xét ở đây
char scoreStr[30] = { 0 };
sprintf(scoreStr, "Score: %d", score);
label->setString(scoreStr);

// Xuất hiện đủ 50 chú chuột thì kết thúc game
if (totalSpawns >= 50) {
Size winSize = Director::getInstance()->getWinSize();
// Kết thúc game
LabelTTF *goLabel = LabelTTF::create("Game Over!", "fonts/Marker Felt.ttf", 48.0f);
goLabel->setPosition(Point(winSize.width / 2, winSize.height / 2));
goLabel->setScale(0.1f);
this->addChild(goLabel, 10);
goLabel->runAction(ScaleTo::create(0.5f, 1.0f)); // Tạo hoạt cảnh 1 tí cho đẹp

gameOver = true; // gán game Over = true để timeline sau ko hiện ra label kết thúc game nữa, bạn test = false xem sẽ thấy
return;
}
//-----------
// Code vòng for ở bài trước vẫn thế nhé vẫn thế nhé

}

2 Hàm khóa và mở khóa trạng thái " được đập" và "ko được đập "

void HelloWorld::setTappable(Object* pSender) // được phép đập
{
Sprite *mole = (Sprite *)pSender;
mole->setTag(1); // cho phép đập
//Play âm thanh, --- Cứ cười đi rồi ăn đập nhá ku!
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("laugh.mp3");
}

void HelloWorld::unsetTappable(Object* pSender)
{
Sprite *mole = (Sprite *)pSender;
mole->setTag(0); // Ko cho phép đập
}

Giờ còn mỗi hàm PopMole này nữa là xong

void HelloWorld::popMole(Sprite *mole)
{
if (totalSpawns > 50) return; // Kết thúc khi đủ 50
totalSpawns++; // đếm số chuột thò lên

// Lệnh này ko rõ lắm, vì bỏ đi game vẫn chạy mole->setSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("mole_1.png"));

// Action của chuột, nhô lên, thụt xuống
auto moveUp = MoveBy::create(0.2f, Point(0, mole->getContentSize().height));  // 1
auto easeMoveUp = EaseInOut::create(moveUp, 3.0f); // 2
auto easeMoveDown = easeMoveUp->reverse(); // 3

// Aimaition Cười
Animate *laugh = Animate::create(laughAnim);

// Thực hiện tuần tự các Action: Thò lên, MỞ BỤP, Cười, KHÓA ĐẬP, Thụt xuống
mole->runAction(Sequence::create(easeMoveUp, 
CallFuncN::create(CC_CALLBACK_1(HelloWorld::setTappable, this)),
laugh,
CallFuncN::create(CC_CALLBACK_1(HelloWorld::unsetTappable, this)),
easeMoveDown, 
NULL)); // 5
}

Xong hết code rồi, BUILD & BỤP thôi anh em




  
OK. Vậy là chúng ta đã ngâm cứu xong 1 game nhẹ nhàng nữa rồi. Cũng không quá khó nhỉ, các bạn nhớ đọc lại code vài lần nhé để nhớ cho lâu.

Vì là bản game TUT nên vẫn còn một số hạn chế:

+ Không có búa đập cho đã tay
+ Đập vào đầu chuột hiệu ứng chưa đẹp, và rõ ràng lắm
+ Điểm số label, không đẹp bằng image
+ Hơi ít lỗ chuột, làm nhiều 1 chút là đập mỏi tay, hỏng màn hình như chơi
+ Thêm vài màn chơi nữa là đẹp
+ Thêm được phần Pause game cũng ko tồi

- Đó là một số phần mở rộng của game, các bạn có thể xây dựng thêm, và mở rộng tới đâu là tùy thuộc ý tưởng của mỗi người nữa. Mình chỉ tới đây thôi.

Chào và hẹn gặp lại các bạn ở những bài sau.

More about

Hẹn giờ tắt máy bằng Lệnh đơn giản trên win

Người đăng: share-nhungdieuhay on Thứ Năm, 3 tháng 7, 2014

Hẹn giờ tắt máy tính bằng lệnh !!!
Đây sẽ là 1 chọn lựa thích hợp cho những bạn thích nghe nhạc trước khi đi ngủ, vì chỉ cần 1 dòng lệnh, máy tính sẽ tự động tắt. Việc còn lại của bạn chỉ là nằm thưởng thức và... ngủ

---------------------------------------------------
* Đối với Windows XP:

Bạn vào Start > Run > gõ "cmd" : để hiển thị cửa sổ dòng lệnh.
Muốn biết cấu trúc lệnh shutdown thì gõ:
Code:
shutdown -\
Cấu trúc lệnh có thể được hiểu đơn giản như sau:

shutdown [option] [-t xx]

Trong đó, option có các tùy chọn:
-s : shutdown
-r : restart
-a : abort (hủy lệnh tắt máy, nếu đã lỡ hẹn tắt bằng dòng lệnh rồi thì chỉ có cách này mới hủy lệnh được  )
....... và nhiều tùy chọn khác, tốt nhất bạn nên xem cấu trúc của lệnh shutdown như đã trình bày từ đầu.

Và, xx là thời gian tắt máy, được tính bằng giây.

Vd: Bạn muốn máy tính tự động tắt sau 15 phút thì gõ:

Code:
shutdown -s -t 900
-----------------------------------------------------
* Đối với Windows Vista:

Cấu trúc lệnh có hơi khác. Bạn bào Start, gõ "cmd": để ra chế độ dòng lệnh.

Và xem cấu trúc lệnh shutdown cũng bằng lệnh:
Code:
shutdown -\
-------------------------------------------------------

Lưu ý: Khi bạn đã quen với cấu trúc lệnh, bạn có thể gõ lệnh trực tiếp tại cửa sổ Run (Start > Run hoặc bấm Win + R) . Khi bạn đã hẹn giờ xong, chỉ cần mở nhạc và bấm Win + L để lock màn hình lại, tắt màn hình và ... ngủ. Máy tính sẽ tự tắt.


------------------------------------------------------
* Đối với Linux (cụ thể mình dùng Ubuntu):

Xem cấu trúc lệnh shutdown:
Code:
shutdown --help
Như ví dụ trên, để tắt máy chỉ cần gõ:
Code:
sudo shutdown -P +15
Sau đó bấm Ctrl + Alt + L để lock màn hình lại. Vậy là không ai *****ng được tới máy tính mình.

đã Test, Nhưng xin lưu ý với các bạn là nếu treo máy mà các bạn vẫn bật Yahoo, FlashFXP đang up hoặc down, và một số chương trình khác mà hệ điều hành ko tự log được thì máy sẽ ko thể tắt vì vậy, trước khi dùng lệnh chỉ nên bật các chương trình như nghe nhạc hoặc IDM ... thanks và danh vọng cho bạn nha
More about

Bài 26: Học làm game thứ 4 - Game đập chuột ( Part 1)

Người đăng: share-nhungdieuhay

Hi cả nhà!

Lâu lâu lại lười viết bài, vì thật ra cũng càng ngày càng khó, và project cũng dài nữa nên.... Và mình cũng đang bí ở phần áp dụng Box2D body cho Animation SpriteSheet, và Box2D body cho CocoStudio, Spine. Tìm hiểu mãi mà chưa có cách làm. Bạn nào đã từng code với bản 2.x có đoạn code áp cho 1 trong 3 cái trên thì chia sẻ giúp nhé, cám ơn.

Hôm nay mình tìm được 1 game khá thú vị, đưa lên đây cho mọi người cùng tìm hiểu, code khá đơn giản, chủ yếu là ôn tập lại các kiến thức đã học thôi, không phức tạp lắm đâu. Đó là game Đập chuột ( Whack Hole ).

Trong này có 1 -3 chú chuột chũi nhô lên, thụt xuống ở 3 cái lỗ, nhiệm vụ của bạn là đập vào đầu nó để ghi điểm thôi. Trong Part 1 ngày, chúng ta nghiên cứu những vấn đề sau

+ Thay đổi tỉ lệ màn hình với từng loại thiết bị
+ Dựng Scene
+ Action của Chuột

Thế thôi nhỉ, ta bắt đầu!

B1 - Thay đổi tỉ lệ màn hình theo từng loại thiết bị

Bạn tạo mới Project dapchuot, mở file AppDelegate.cpp ra, thêm vào đoạn code sau, bên dưới lệnh director->setAnimationInterval(1.0 / 60);

    // Màn hình thiết bị
    Size frameSize = glview->getFrameSize();  
    auto designSize = Size(512, 384);  // Khung hình thiết kế

    // Độ phân giải thiết kế
    glview->setDesignResolutionSize(designSize.width, designSize.height, ResolutionPolicy::NO_BORDER);

    // Vector <string> lưu thông tin đường dẫn Resource
    std::vector<std::string> searchPaths;
    if (frameSize.height > 480)  // Nếu màn hình > 480
    {
        searchPaths.push_back("hd"); // đường dẫn là ("hd");
        Size resourceSize = Size(1024, 768); // Đặt kích thước = 1024,768


        // Tăng kích thước content để phù hợp với màn hình
        director->setContentScaleFactor(MIN(resourceSize.height/designSize.height,
                                            resourceSize.width/designSize.width));
    }
    else //  Chọn sd< 480px
    {
        searchPaths.push_back("sd");
    }

    // Chọn Resource
    FileUtils::getInstance()->setSearchPaths(searchPaths);

B2 - Dựng màn chơi 

Bạn mở file HelloWorldScene.h, thêm vào đoạn code sau

void tryPopMoles(float dt);  // 1 hàm rất giống hàm update ( float dt ) đúng ko, thì chức năng cũng giống thế mà, update scene theo thời gian
void popMole(Sprite *mole); // Hàm acction cho chuột

Vector<Sprite*> molesVector; // Vector Sprite lưu các chú chuột

Mở HelloWorldScene.cpp

Trong hàm init (), thêm 1 đoạn code khá dài sau ( xóa phần code thừa bên trong, chỉ chừa lại phần super init() và return true nhé)

    // Đặt tên cho các file Resource, lưu ý 1 chút với string nó thuộc lớp std nên phải khai báo dạng std::string. Nếu không muốn thế này bạn phải dùng namespace: using namespce std; ở đầu file
    
    // Các dạng file này .pvr.ccz, .plist nhìn có vẻ ghê ghớm nhưng thực ra không có gì cả. File .plist chứa thông tin tọa độ, tên gọi, kích thước của các ảnh png đơn lẻ được pack trong file .pvr.ccz. Còn file .pvr.ccz là 1 dạng nén ảnh để giảm kích thước lưu trữ và bộ nhớ trong game. Bạn dùng phần mềm TexturePacker 3.3.x trong Blog này mình có bài rồi để thực hiện pack nhé

    std::string bgSheet = "background.pvr.ccz";
    std::string bgPlist = "background.plist";
    std::string fgSheet = "foreground.pvr.ccz";
    std::string fgPlist = "foreground.plist";
    std::string sSheet  = "sprites.pvr.ccz";
    std::string sPlist  = "sprites.plist";
    
    // Nạp background + foreground
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(bgPlist);
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(fgPlist);
    
    // Add background, bg_dirt.png được lấy từ background.pvr.ccz (  dựa trên thông số của background.plist)
    Sprite *dirt = Sprite::createWithSpriteFrame(
                        SpriteFrameCache::getInstance()->getSpriteFrameByName("bg_dirt.png"));
    dirt->setScale(2.0); // Phóng to lên
    dirt->setPosition(winSize.width/2, winSize.height/2);
    this->addChild(dirt, -2);

    // Add foreground, grass_lower.png lấy trong foreground.pvr.ccz ( dựa trên thông số của foreground.plist )
    // Nửa dưới
    Sprite *lower = Sprite::createWithSpriteFrame(
                        SpriteFrameCache::getInstance()->getSpriteFrameByName("grass_lower.png"));

    // Bạn chú ý chỗ này, 1 hình ảnh có nhiều AnchorPoint ( là điểm engine sẽ lấy để đặt trên màn hình vào tọa độ xác định. thường có 9 AnchorPoint hay dùng là các điểm sau: 4 góc hình + 1 tâm + 4 trung điểm 4 cạnh của khung ảnh png
    //Như thế này 
    //Point(0,0) = góc trái-dưới
    //Point(0,1) = góc trên-trái
    //Point(1,0) = góc phải-dưới
    //Point(1,1) = góc trên-phải
    //Point(0.5,0.5) = Tâm
    //Point(0.5,0) = giữa cạnh dưới
    //Point(0,0.5) = giữa cạnh trái
    //Point(0.5,1) = giữa cạnh trên
    //Point(1,0.5) = giữa cạnh phải
    // Với hình đặc biệt trong CocoStudio, Spine, SpriteSheet, ta có thể chỉnh được điểm neo này = tay
    // Tùy vào từng trường hợp mà ta set AnchoPoint hợp lý sẽ khiến việc căn đối tượng dễ dàng hơn

    lower->setAnchorPoint(Point(0.5, 1));
    lower->setPosition(winSize.width/2, winSize.height/2 + 1); // Tách 2 nửa ra 1 chút để nhận biết, trong game bạn xóa + 1 đi
    this->addChild(lower, 1);

    // Nửa trên, tại sao có nửa dưới và trên ? khi bạn build xong sẽ hiểu, vì nửa trên set index -1, nửa dưới =1 để cho chuột có index ở giữa = 0 sẽ hiện bên trên nửa trên và bị che một phần do nửa dưới. giá trị index có tác dụng sắp sếp đối tượng như thế.

    Sprite *upper = Sprite::createWithSpriteFrame(
                        SpriteFrameCache::getInstance()->getSpriteFrameByName("grass_upper.png"));
    upper->setAnchorPoint(Point(0.5, 0));
    upper->setPosition(winSize.width/2, winSize.height/2 - 1); // Tách 2 nửa ra 1 chút để nhận biết, trong game bạn xóa - 1 đi
    this->addChild(upper, -1);
    
// Tạo SpriteSheet... lưu chuột
SpriteBatchNode *spriteNode = SpriteBatchNode::create(sSheet);
this->addChild(spriteNode, 0);
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(sPlist);

// Nạp 3 chuột
Sprite *mole1 = Sprite::createWithSpriteFrameName("mole_1.png");
mole1->setPosition(99, winSize.height / 2 - 75);
spriteNode->addChild(mole1); // Thêm vào spritesheet
molesVector.pushBack(mole1); // Thêm vào Vector

Sprite *mole2 = Sprite::createWithSpriteFrameName("mole_1.png");
mole2->setPosition(winSize.width / 2, winSize.height / 2 - 75);
spriteNode->addChild(mole2);
molesVector.pushBack(mole2);

Sprite *mole3 = Sprite::createWithSpriteFrameName("mole_1.png");
mole3->setPosition(winSize.width - 102, winSize.height / 2 - 75);
spriteNode->addChild(mole3);
molesVector.pushBack(mole3);

// Update scene trong thời gian 0.5 giây
this->schedule(schedule_selector(HelloWorld::tryPopMoles), 0.5);

Hàm tryPopMoles như sau

void HelloWorld::tryPopMoles(float dt) // hàm này nhận đối số thời gian giống hàm update (float dt)
{
for (Sprite *mole : molesVector) // duyệt vector
{
int temp = CCRANDOM_0_1()*10000; // Tạo số random
if ( temp % 3 == 0)  // chia hết cho 3, thì ....
{
if (mole->getNumberOfRunningActions() == 0)  // Nếu ko có Action nào
{
this->popMole(mole); // Thò đầu lên và ăn đập : ))
}
}
}
}

B3 - Hành động của chuột

void HelloWorld::popMole(Sprite *mole)
{
// Lên 
auto moveUp = MoveBy::create(0.2f, Point(0, mole->getContentSize().height));  // 1
auto easeMoveUp = EaseInOut::create(moveUp, 3.0f); // 2

auto easeMoveDown = easeMoveUp->reverse(); // 3
auto delay = DelayTime::create(0.5f); // 4

// Thực hiện chuỗi hành động, Lên, đứng đó, Xuống, ko làm gì cả 
mole->runAction(Sequence::create(easeMoveUp, delay, easeMoveDown, NULL)); // 5
}

Xong rồi, Build chạy thử xem có ra gì không, ngon rồi!




Vậy là trong bài này chúng ta cùng nhau ôn lại 1 vài kiến thức sau:

+ SpriteSheet
+ Nạp Resource từ file Pvr, plist
+ Vector
+ Action

Đơn giản thế thôi, bài sau chúng ta sẽ thực hiện nốt công việc là, đập chuột, tính điểm.

Dowload Resoucrce, Class

Chào và hẹn gặp lại các bạn ở bài sau!

Bài 27: Học làm game thứ 4 - Game đập chuột ( Part 2) 
More about

Bài 25 - Tìm hiểu về hiệu ứng Parallax Scrolling trong Cocos2d-x 3.x

Người đăng: share-nhungdieuhay on Thứ Tư, 2 tháng 7, 2014

Hi các bạn! 

Lang thang trên trang chủ của cocos2d-x gặp được 1 bài TUT về Parallax Crolling khá hay, mình mang về Blog này để mọi người cùng ngâm cứu. Có thể nhiều bạn sẽ nghĩ mình đang "ăn cắp" bài viết của người khác làm bài của mình. Oh no, biết nói thế nào nhỉ, ngay từ ban đầu blog ( bài 1,2 gì đó) mình đã nói rõ, Code, Resource trong Blog này mình ko hề Code ra, mà chỉ nhặt nhạnh trên mạng, rồi đem về trình bày và diễn giải lại trên Blog để tự học và mọi người cùng đọc. Có nhiều bài mình thực hành code xong viết lại thành TUT, hoặc có 1 vài bài mình lấy Tut người khác, nhưng sẽ trình bày lại theo cách hiểu của mình sao cho dễ hiểu và gần gũi với cả người mới bắt đầu tìm hiểu về Engine, và đây là 1 bài như thế. Sẽ không có gì quá đáng phải không, mà thôi, ai đánh giá thế nào thì kệ chứ, việc của chúng ta là HỌC, là NGÂM CỨU làm game chứ ko phải VIẾT SÁCH, VIẾT TUT! 

OK, trước tiên chúng ta cùng tìm hiểu 1 hiện tượng vật lý cực kỳ hay gặp trong cuộc sống, đó là Parallax Scrolling

Parallax Scrolling  là gì? Dùng trong trường hợp nào?

Từ Parallax có nghĩa là Thị sai trong tiếng Việt đó
Bạn gõ Parallax hoặc Thị sai lên Google là sẽ có kết quả trả về lập tức, đây là trang Wiki

Hiện tượng Parallax Scrolling là hệ quả được tạo ra bởi thị sai ( Parallax ) của mắt với các vật thể xa, gần, Vật càng xa, góc nhìn càng nhỏ, vật càng gần thì góc nhìn càng rộng, nêu khi 2 vật xa gần di chuyển cùng 1 vận tốc ( hoặc khác vận tốc ), thì ta sẽ thấy vật ở gần (có vẻ ) di chuyển nhanh hơn vật ở xa.

Chúng ta có thể hiểu Hiệu ứng Parallax Scrolling là hiệu ứng các vật chuyển động tương đối với vận tốc tỷ lệ nghịch với khoảng cách từ vật tới mắt người quan sát, Vật gần di chuyển nhanh, vật xa di chuyển chậm

Ví dụ về Prallax trên HTML5 
Ví dụ trong cuộc sống hàng ngày
+ Khi bạn đi tàu, xe, nhìn ra ngoài cửa sổ sẽ thấy, Cột điện "lùi lại rất nhanh", cánh đồng "lùi lại vừa phải", Mây "lùi lại chậm" Mặt trời "lùi lại rất chậm". Nghĩa là vật càng gần mắt người quan sát thì chuyển động càng nhanh, càng ở xa thì chuyển động càng chậm. ( mặc dù các vật trên có thể coi là cùng vận tốc - đứng im - so với mắt người đang đứng im ) đừng ai bắt bẻ về "sự đứng im" và chuyển động nhé. cũng chỉ tương đối thôi, quan trọng là mắt người quan sát thấy thế nào thôi.

Ứng dụng trong game:

Hiệu ứng Parallax Scrolling hay dùng trong game 2D để tạo chiều sâu cho game, bạn hãy vào trang web bên trên trải nghiệm nhé, 

Tạo hiệu ứng này như thế nào?

Dựa vào định nghĩa trên, về lý thuyết thì ta có thể làm như sau trong game

+ Ta tạo ra Các layer chồng lên nhau
+ Layer nào ta định nghĩa ở xa thì ta cho dịch chuyển với tốc độ chậm
+ Layer nào định nghĩa ở gần thì ta dịch chuyển với tốc độ nhanh hơn
+ Các vận tốc này thường cùng phương cùng chiều, độ lớn tỷ lệ với khoảng cách đến mắt quan sát

Lý thuyết có vẻ đơn giản, thực tế Code thì sao?

Chúng ta cùng bắt đầu nào!


Bạn tạo 1 Project mới đặt tên Parallax

Xây dựng Class InfiniteParallaxNode như sau

InfiniteParallaxNode.h

class InfiniteParallaxNode : public ParallaxNode
{
public:
    static InfiniteParallaxNode* create(); // Tạo InfiniteParallaxNode
    void updatePosition(); // Update lại vị trí
};

InfiniteParallaxNode.cpp

class PointObject : public Ref // Dựng 1 lớp PointObject
{
public:

    // Các hàm inline thiết lập, và lấy về các thuộc tính
    inline void setRation(Point ratio) {_ratio = ratio;}
    inline void setOffset(Point offset) {_offset = offset;}
    inline void setChild(Node *var) {_child = var;}
    inline Point getOffset() const {return _offset;}
    inline Node* getChild() const {return _child;}

private:
    Point _ratio; // Tỉ lệ
    Point _offset; // Độ lệch
    Node* _child; // Node con
};

InfiniteParallaxNode* InfiniteParallaxNode::create()
{
    // Tạo mới 1 đối tượng InfiniteParallaxNode*
    InfiniteParallaxNode* node = new InfiniteParallaxNode();
    if(node) {
        node->autorelease();
    } else {
        delete node;
        node = 0;
    }
    return node;
}

void InfiniteParallaxNode::updatePosition()
{
    int safeOffset = -10;

    Size visibleSize = Director::getInstance()->getVisibleSize();
    // 1. Duyệt các con của chuỗi parallax

    for(int i = 0; i < _children.size(); i++)
    {
        auto node = _children.at(i); // Node i
        // 2. Kiểm tra node đó có ra ngoài màn hình ko, convertToWorldSpace bạn tham khảo tại đây http://www.cocos2d-x.org/wiki/Coordinate_System.
        if(convertToWorldSpace(node->getPosition()).x + node->getContentSize().width < safeOffset)
            // 3. Tìm PointObject tương ứng với node hiện tại
            for(int j = 0; j < _parallaxArray->num; j++)
            {
                auto po = (PointObject*)_parallaxArray->arr[j];
                // Nếu có thì tăng thêm độ lệch ra thêm 1 màn hình, tức xuất hiện lại thêm lần nữa
                if(po->getChild() == node)
                    po->setOffset(po->getOffset() +
                                  Point(visibleSize.width + node->getContentSize().width,0));
            }
    }
}

Trong file HelloWorldScene.h

Thêm include

    #include "InfiniteParallaxNode.h"
    InfiniteParallaxNode* _backgroundElements; // 1 con trỏ InfiniteParallaxNode
    float randomValueBetween(float low, float high); // random trong 1 khoảng
    void update(float delta); 

Trong file HelloWorldScenecpp

Phần Include

#include <climits>
#include <cstdlib>
#include <iostream>
using namespace std;

2 Hàm phụ

void HelloWorld::update(float delta)
{
    Point scrollDecrement = Point(5, 0); // Tốc độ Scroll, càng lớn cuộn càng nhanh
    _backgroundElements->setPosition(_backgroundElements->getPosition() - scrollDecrement);
    _backgroundElements->updatePosition();
}

// Giá trị ngẫu nhiên trong 1 khoảng
float HelloWorld::randomValueBetween(float low, float high)
{
    return (((float) rand() / RAND_MAX) * (high - low)) + low;
}

Hàm init()

    // Tạo màu nền cho background
    auto backgroundColor = LayerColor::create(
                Color4B(173, 255, 250, 255),
                visibleSize.width,
                visibleSize.height);
    backgroundColor->setPosition(Point::ZERO);
    addChild(backgroundColor, 0);
    // Ảnh Background
    auto ground = Sprite::create("ground.png");
    ground->setAnchorPoint(Point(0,0));
    ground->setPosition(Point::ZERO);
    addChild(ground, 1);
    
    // Tạo 1 đối tượng Parallax
    _backgroundElements = InfiniteParallaxNode::create();

    // Thêm 7 đối tượng (núi tuyết) vào Parallax
    unsigned int rocksQuantity = 7;
    for(unsigned int i = 0; i < rocksQuantity; i++)
    {
        auto rock = Sprite::create("rock.png");
        rock->setAnchorPoint(Point::ZERO);
        // Đặt độ lớn theo tỷ lệ ngẫu nhiên
        rock->setScale(randomValueBetween(0.6, 0.75));
        // Thêm vào Parallax
        _backgroundElements->addChild(rock,
                                     // Z-index, index lớn thì nằm chồng lên index nhỏ
                                     randomValueBetween(-10, -6),
                                     // Tỉ lệ tốc độ ( sẽ nhân với tốc độ Paralax)
                                     Point(0.05, 1),
                                     // Đặt vị trí của đối tượng, các đối tượng sẽ đặt cách nhau 1 khoảng tính theo công thức như bên dưới
                                     Point(
                                         (visibleSize.width / 5) * (i + 1) + randomValueBetween(0, 100),
                                         ground->getContentSize().height - 5));
    }

    // Thêm 35 cái cây vào Parralax
    unsigned int treesQuantity = 35;
    for(unsigned int i = 0; i < treesQuantity; i++)
    {
        auto tree = Sprite::create("tree.png");
        tree->setAnchorPoint(Point::ZERO);
        tree->setScale(randomValueBetween(0.5, 0.75));
        _backgroundElements->addChild(
                    tree,
                    randomValueBetween(-5, -1),
                    Point(0.5, 1),
                    Point(visibleSize.width / (treesQuantity - 5) * (i + 1) + randomValueBetween(25,50),
                          ground->getContentSize().height - 8));
    }

    // Thêm Parallax vào :Layer, update Scene
    addChild(_backgroundElements, 2);

    schedule(schedule_selector(HelloWorld::update), 0.01);

    // Thêm cha mặt trời vào 
    auto sun = Sprite::create("sun.png");
    sun->setAnchorPoint(Point(0.5,0.5));
    sun->setScale(0.25);
    sun->setPosition(Point(visibleSize.width * 2.0 / 3, visibleSize.height * 6.0 / 7));
    addChild(sun, 3);


OK rồi, giờ build và chạy thử xem thế nào



Vậy là trong bài này, chúng ta đã cùng nhau tìm hiểu về hiệu ứng Parallax Scrolling rồi đó. Bạn có thể áp dụng vào các game Running..X nào đó để làm game có chiều sâu hơn.

Một số hạn chế: 
+ Bạn phải ước lượng tỉ lệ vận tốc giữa các "Layer" Parallax ( vì thực sự đâu có nhiều Layer đâu - Chỉ có 1 Paralax ) do không biết được "khoảng cách" giữa các lớp này. 
+ Khi mô phỏng bạn làm sao cho các đối tượng gần thì chuyển động nhanh, các đối tượng xa thì chuyển động chậm hơn. Vậy thôi.

Dowload Resource, Code

Mình kết thúc bài này ỏ đây nhé, hẹn gặp lại trong các bài sau

Bài 26 : Học làm game 4 - Đập chuột ( Part 1 )
More about

Code C/C++: Thuật toán Prim tìm cây bao trùm tối thiểu

Người đăng: share-nhungdieuhay

Mô tả bài toán: cho đồ thị vô hướng có trọng số G=(V,E) hãy tìm đường đi sao cho tất cả các đỉnh điều có đường đi với nhau và tổng trọng số của đường đi là nhỏ nhất.
Ý tưởng thuật toán:
Bước 1: xuất phát từ đỉnh k bất kỳ (thông thường chọn đỉnh đầu tiên) chọn một cạnh có trọng số nhỏ nhất liền kề với đỉnh k (min{A[k][j]}j=1..n) ta đánh dấu 2 đỉnh đi qua cạnh đó và số cạnh tìm được là 1. Chuyển sang Bước 2.
Bước 2: tìm cạnh nhỏ nhất của đồ thị với điều kiện cạnh tìm được phải có 1 đỉnh chưa đánh dấu và 1 đỉnh đã đánh dấu. Nghĩa là, ta tìm min{A[i][j]} j=1..n, i=1..n sao cho i đánh dấu và j chưa đánh dấu để tránh trường hợp tạo thành chu trình con. Ta tăng số cạnh tìm được lên 1 và chuyển sang Bước 3.
Bước 3: nếu số cạnh tìm được bằng n-1 kết thúc thuật toán, ngược lại quay về Bước 2.
Mô tả dữ liệu đầu vào và đầu ra của bài toán:
Dữ liệu vào: lưu trong tập tin Bai7.inp
-  Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100)
-  Dòng i+1 (1<=i<=n) lưu ma trận kề của đồ thị với n số A[i,1], A[i,2],…, A[i,n] mỗi số cách nhau bởi một khoảng trắng.
Dữ liệu ra: lưu trong file Bai7.out
-  Dòng đầu ghi trọng số nhỏ nhất của cây bao trùm.
-  Các dòng còn lại lưu đường đi giữa đỉnh i nối với đỉnh j.
Ví dụ:

Cài đặt chương trình:
#include <stdio.h>
#include <values.h>
#define max 100
#define FileInt "Bai7.inp"
#define FileOut "Bai7.out"
typedef struct Egde{
int x,y;
}; 
//đọc dữ liệu từ tập tin
void Doc_File(int A[max][max],int &n) {
FILE*f = fopen(FileInt,”rb”);
fscanf(f,”%d”,&n);
for(int i =0;i<n;i++) {
for(int j =0;j<n;j++) {
fscanf(f,”%d”,&A[i][j]);
}
}
fclose(f);
}
//ghi dữ liệu ra tập tin
void Ghi_File(Egde L[max],int n,int Sum) {
FILE*f = fopen(FileOut,"wb");
fprintf(f,"%d\n",Sum);
for(int i =0; i<n-1; i++)
fprintf(f,"%d -%d\n",L[i].x+1,L[i].y+1);
fclose(f);
}
//thuật toán Prim
void Prim(int A[max][max], int n) {
char D[max];
Egde L[max];
int min = MAXINT, Dem = 0, Sum = 0;
for(int i=0; i<n; i++)
D[i]=0;
for(int j=1; j<n; j++)
if(min>A[0][j] && A[0][j]!=0){
min = A[0][j];
L[0].y = j;
}
L[0].x = 0;
D[0] = 1;
D[L[0].y] = 1;
Sum+=min;
Dem++;
do {
min = MAXINT;
for( i=0; i<n; i++)
if(D[i]==1)
for( j=0; j<n; j++)
if(A[i][j]>0 && min>A[i][j] && D[j]==0){
min = A[i][j]; 
L[Dem].x = i;
L[Dem].y = j;
}
Sum+=min;
D[L[Dem].y] = 1;
Dem++;
} while(Dem<n-1);
Ghi_File(L,n,Sum);
}
//chương trình chính
void main() {
int A[max][max],n;
Doc_File(A,n);
Prim(A,n);

}
Tags: Kỹ thuật lập trình, toán rời rạc, c, c++, prim, cây khung
More about