เมื่อถูกท้าทาย
หลังจากที่ไม่ได้เปิด Facebook มานาน วันนี้ลองเข้าไปดูเล่น ๆ ปรากฎว่ามี Invitation มาให้เล่นเกมส์ word challenge
ไอ้เราก็ลองเล่นไปเล่นมา รู้สึกสนุกดีนะ แต่คิดศัพย์ไม่ค่อยออกเลย ก็เลยเขียน script มาช่วยค้นหาศัพย์ ซึ่งเขียนด้วย perl
ก่อนอื่นก็ไปหา dictionary ก่อนเลยไม่ค่อยมีที่ถูกใจ จนมาพบกับ web นึงซึ่งค่อนข้างดูแปลก (รึเปล่า)
นั่นคือ http://zyzzyva.net/ ตรงข้างล่างมีรวบรวมศัพย์หลาย ๆ แบบ เราก็เลยจับเอามายำกันซะ ให้เหลือศัพย์ที่มีความยาว 3 - 6 ตัวอักษร
จากนั้นก็เขียน perl เพื่อมา search ศัพย์จากตัวอักษรที่มีอยู่ ซึ่ง algorithm ไม่มีอะไรมาก คืออ่าน file เข้ามาแล้วก็ก็จัดการเรียงตัวอักษรซะใหม่ แล้วจึงค่อยจัดเก็บเข้า mem แบบ hash จะได้ไม่ต้องมาวน loop เพื่อ search หลาย ๆ รอบ จากนั้นก็ส่วนของการรับ input ก็เขียนให้เอาตัวอักษรมา 3 - 6 ตัวทุก combination มา search ใน hash ที่เตรียมไว้
ตอนแรกก็พิมพ์ตาม ศัพย์ที่มีใน dictionary นั่นแหละ แต่ทำไปทำมาชักไม่สะดวก โชคดีที่ perl มี Module ชื่แ Win32::GuiTest ซึ่งมีคำสั่ง Sendkey ของ windows… เสร็จโจรเลยหล่ะ ทีนี้ ผลลัพธ์ที่ได้คือ… ดัง VDO
ส่วน code นั้นก็เขียนแบบง่ายๆ มีเนื้อหาดังนี้
use Win32::GuiTest qw(FindWindowLike GetWindowText
SetForegroundWindow SendKeys);
use Win32::Clipboard;
load_word();
$min = 3;
$max = 6;
while(1)
{
print "Input : ";
$input = ;
chomp($input);
SetForegroundWindow(658262);
doit($input);
}
sub doit
{
my $set = shift;
@answer = "";
@list2 = "";
for(my $i=$max;$i >= $min;$i--)
{
@list = "";
find_com($set,"",0,$i);
@list = sort(@list);
foreach $l (@list)
{
push @list2,$l;
}
}
my %ww = "";
foreach $l (@list2)
{
if($word{$l})
{
for(my $i = 0;$i < $word{$l}; $i++)
{
if(!$ww{$words{$l}[$i]})
{
#print "$l = $words{$l}[$i]\n";
push @answer, $words{$l}[$i];
$ww{$words{$l}[$i]} = 1;
}
}
}
}
print "\n\n";
@answer = sort {length $a <=> length $b || $a cmp $b} @answer;
foreach $ans (@answer)
{
if($ans eq "")
{
next;
}
if(length($ans) == 6)
{
print ">>> $ans\n";
next;
}
SendKeys("$ans~");
print "Trying $ans\n";
}
print "\n\n";
}
sub find_com
{
my $set = shift;
my $this_text = shift;
my $count = shift;
my $max = shift;
for(my $i = $count;$i < length($set) ; $i++)
{
my $the_text = $this_text . substr($set,$i,1);
if(length($the_text) == $max)
{
my $x = rearrange($the_text);
push @list,$x;
}
elsif(length($set) - $i < $max - $count)
{
return;
}
else
{
find_com($set,$the_text,$i+1,$max);
}
}
}
sub rearrange
{
my $text = shift;
my @tmp;
for(my $i = 0 ; $i < length($text) ; $i++)
{
my $sub = substr($text,$i,1);
push @tmp, $sub;
}
@tmp = sort(@tmp);
return join("",@tmp);
}
sub load_word
{
open(READ,"enable1.txt");
@data = ;
close(READ);
chomp(@data);
my $set = shift;
my $min = 3;
my $max = 6;
foreach $line (@data)
{
if(length($line) < 3 || length($line) > 6)
{
next;
}
$re = rearrange($line);
if(!$word{$re})
{
$words{$re}[0] = $line;
$word{$re} = 1;
}
else
{
$words{$re}[$word{$re}] = $line;
$word{$re}++;
}
}
}
555 สอนกุทำพวกนี้หน่อยดิ อิอิ