diff --git a/app/android/app/build.gradle b/app/android/app/build.gradle index 78a4375..5f81b2e 100644 --- a/app/android/app/build.gradle +++ b/app/android/app/build.gradle @@ -27,6 +27,7 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -43,7 +44,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.guessing_words" + applicationId "com.hellcat.words" minSdkVersion flutter.minSdkVersion targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() diff --git a/app/android/app/src/debug/AndroidManifest.xml b/app/android/app/src/debug/AndroidManifest.xml index 64f7cda..400845d 100644 --- a/app/android/app/src/debug/AndroidManifest.xml +++ b/app/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,7 @@ - diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index 606d2eb..176f9f8 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + package="com.hellcat.words"> diff --git a/app/assets/images/player-sprite.png b/app/assets/images/player-sprite.png new file mode 100644 index 0000000..e4f16b0 Binary files /dev/null and b/app/assets/images/player-sprite.png differ diff --git a/app/assets/words.txt b/app/assets/words.txt new file mode 100644 index 0000000..4b2716b --- /dev/null +++ b/app/assets/words.txt @@ -0,0 +1,5795 @@ +aaron +ababa +abaci +aback +abaft +abase +abash +abate +abbey +abbot +abeam +abets +abhor +abide +abler +abode +abort +about +above +abuja +abuse +abuts +abysm +abyss +accra +ached +aches +acids +acing +acorn +acres +acrid +acted +actes +actin +acton +actor +actum +actus +acute +adage +adams +adapt +addax +added +adder +addis +addle +adeem +adept +adieu +adios +adits +adler +adman +admit +admix +adobe +adopt +adore +adorn +adult +adzes +aegis +aeons +aesop +affix +afire +afoot +afore +afoul +afros +after +again +agape +agars +agate +agent +agers +aggro +agile +aging +agios +agist +aglow +agnes +agony +agree +agues +ahead +aided +aider +aides +ailed +aimed +aired +aires +aisle +akron +alamo +alarm +album +alcms +alder +aleck +alert +alfas +algae +algid +algol +alias +alibi +alice +alien +align +alike +alive +alkyd +alkyl +allah +allan +allay +allen +alley +allot +allow +alloy +aloes +aloft +aloha +alone +along +aloof +aloud +alpha +altar +alter +alton +altos +alvin +amass +amaze +amber +ambit +amble +amend +amica +amici +amide +amies +amigo +amine +amino +amish +amiss +amity +amman +among +amore +amour +ample +amply +amuck +amuse +andes +anent +angel +anger +angle +angli +anglo +angry +angst +angus +anima +animo +anion +anise +anita +anjou +ankle +annex +annie +annis +annos +annoy +annul +annum +anode +anted +antes +antic +antis +anton +anvil +aorta +apace +apart +aphid +aphis +aping +apish +apnea +appal +apple +apply +april +apron +apses +aptly +arabs +arams +arbor +arced +arden +ardor +areas +arena +arere +argil +argon +argos +argot +argue +argus +arias +aries +arils +arise +arles +armed +armis +armor +aroma +arose +arran +arras +array +arrow +arses +arson +artem +artis +aruba +arvin +aryan +aryls +ascii +ascot +ashen +ashes +asian +aside +asked +askew +aspen +aspic +assam +assay +asses +asset +aster +astir +aston +aswan +atlas +atoll +atoms +atone +atria +attar +attic +audio +audis +audit +auger +aught +augur +aunts +aunty +aural +auras +autos +autre +avail +avant +avers +avert +avery +avian +avoid +avows +await +awake +award +aware +awash +awful +awing +awoke +axial +axing +axiom +axles +axons +aztec +azure +babas +babel +babes +backs +bacon +bacup +badge +badly +bagel +baggy +bails +bairn +baits +baize +baked +baker +bakes +baled +baler +bales +balks +balky +balls +balms +balmy +balsa +bambi +banal +banco +bancs +bands +bandy +banff +bangs +banjo +banks +banns +banta +bantu +barbs +barch +bards +bared +barer +bares +barge +barks +barmy +barns +baron +barra +barry +basal +based +basel +baser +bases +basic +basil +basin +basis +basks +basle +basra +baste +batas +batch +bated +bates +bathe +baths +batik +baton +bator +batty +bauer +baulk +bawds +bawdy +bawls +bayed +bayer +bayou +beach +beads +beady +beaks +beams +beans +beard +bears +beast +beats +beaux +bebop +becky +bedel +bedew +beech +beefs +beefy +beeps +beers +beets +befit +befog +began +beget +begin +begot +begun +beige +being +belay +belch +belie +belle +belli +bello +bells +belly +below +belts +bemis +bench +bends +benin +benny +bents +beret +bergs +berms +berry +berth +beryl +beset +bests +betas +betel +betsy +betts +betty +bevel +bezel +bible +biddy +bided +bides +bidet +biens +biers +biggs +bight +bigot +bijou +biked +biker +bikes +bilan +bilbo +bilge +bilks +bills +billy +bimbo +binds +binge +bingo +biome +biota +biped +birch +birds +biros +birth +bison +bitch +biter +bites +bitty +bizet +blabs +blaby +black +blade +blahs +blair +blake +blame +blanc +bland +blank +blare +blas� +blast +blaze +bleak +blear +bleat +blebs +bleed +bleep +blees +blend +bless +blest +bleta +blimp +blind +blink +blips +bliss +blitt +blitz +bloat +blobs +block +blocs +bloke +blond +blood +bloom +blots +blown +blows +blowy +bluer +blues +bluff +blunt +blurb +blurs +blurt +blush +blyth +board +boars +boast +boats +bobby +boded +bodes +bodge +boers +bogey +boggy +bogie +bogus +boils +boise +bolas +boles +bolls +bolos +bolts +bolus +bombe +bombs +bonds +boned +boner +bones +bongo +bongs +bonis +bonny +bonum +bonus +bonze +boobs +booby +booed +books +booms +boons +boors +boost +booth +boots +booty +booze +boozy +borax +bored +borer +bores +boric +boris +borne +boron +bosch +bosky +bosom +boson +bossy +bosun +botch +bothy +bough +bound +bouts +bowed +bowel +bower +bowes +bowie +bowls +boxed +boxer +boxes +boyar +boyce +boyle +bozos +brace +brach +bract +brads +braes +brags +braid +brain +brake +brand +brash +brass +brats +brava +brave +bravo +brawl +brawn +brays +braze +bread +break +bream +breed +brent +brest +breve +brews +brian +briar +bribe +brick +bride +brief +brier +brigg +brigs +brill +brims +brine +bring +brink +briny +brisk +brits +broad +broil +broke +bronx +brood +brook +broom +broth +brown +brows +bruce +bruin +bruit +brume +bruno +brunt +brush +brute +bryan +bucks +buddy +budge +buffo +buffs +buggy +bugle +buick +build +built +bulbs +bulge +bulgy +bulks +bulky +bulls +bully +bumph +bumps +bumpy +bunch +bungs +bunks +bunny +bunts +buoys +burgh +burgs +burin +burke +burls +burly +burma +burns +burnt +burps +burro +burrs +burst +buses +bushy +busks +busts +butch +butte +butts +butyl +buxom +buyer +byers +bylaw +byres +byron +bytes +byway +cabal +cabby +caber +cabin +cable +cabot +cacao +cache +cacti +caddy +cadet +cadge +cadiz +cadre +cafes +caged +cages +cagey +cairn +cairo +cajun +caked +cakes +calls +calms +calve +calyx +camas +camel +cameo +camps +campy +camus +canal +canap +candy +caned +canes +canna +canny +canoe +canon +canto +cants +capax +caper +capes +capon +capri +caput +carat +cards +cared +cares +caret +carew +carey +cargo +carib +carne +carob +carol +carom +carpe +carps +carry +carta +carte +carts +carve +cased +cases +casey +casks +caste +casts +casus +catch +cater +cathy +catty +caulk +causa +cause +cavan +caved +caves +cavil +cawed +cchem +cease +cecil +cedar +ceded +cedes +cedit +celia +cello +cells +celts +cents +ceorl +cepit +certi +chace +chafe +chaff +chain +chair +chalk +champ +chant +chaos +chaps +chard +charm +chars +chart +chary +chase +chasm +chats +cheam +cheap +cheat +check +cheek +cheep +cheer +chefs +chess +chest +chews +chewy +chick +chide +chief +child +chile +chili +chill +chime +chimp +china +chine +chink +chino +chins +chips +chirp +chits +chive +chivy +chock +choir +choke +choko +chomp +chops +chord +chore +chose +choux +chows +chris +chubb +chuck +chuff +chugs +chump +chums +chunk +churl +churn +chute +cider +cigar +cilia +cinch +cindy +circa +cirri +cista +cited +cites +civet +civic +civil +civvy +clack +claim +clamp +clams +clang +clank +clans +claps +clare +clark +clash +clasp +class +claus +claws +clays +clean +clear +cleat +clefs +cleft +clerk +clews +clich +click +cliff +climb +clime +cline +cling +clink +clint +clips +clive +cloak +clock +clods +clogs +clomp +clone +clops +close +cloth +clots +cloud +clout +clove +clown +cloys +clubs +cluck +clued +clues +clump +clung +clwyd +clyde +coach +coals +coast +coati +coats +cobol +cobra +cocas +cocks +cocky +cocoa +codas +coded +codes +codex +cogit +cohan +cohen +coifs +coils +coins +coked +cokes +colas +colds +colic +colin +colne +colon +color +colts +comas +combo +combs +comer +comes +comet +comex +comfy +comic +comma +comps +conch +condo +coned +cones +coney +conga +congo +conic +conks +conwy +cooed +cooks +cools +coomb +coons +coops +coors +coots +copal +coped +copes +coppa +copra +copse +copts +coral +coram +corby +cords +cored +corer +cores +corey +corfu +corgi +corks +corky +corms +corns +corny +corps +cosec +cosen +costa +costs +cotta +couch +cough +could +count +coupe +coups +court +coven +cover +coves +covet +covey +covin +cowed +cower +cowes +cowls +cowry +coyer +coyly +coypu +cozen +crabs +crack +craft +crags +craig +crake +cramp +crams +crane +crank +crape +craps +crash +crass +crate +crave +crawl +craws +craze +crazy +crche +creak +cream +credo +creed +creek +creel +creep +creme +crepe +crept +cress +crest +crete +crewe +crews +cribs +crick +cried +crier +cries +crime +crimp +crisp +croak +croat +crock +croft +crone +crony +crook +croon +crops +cross +croup +crowd +crown +crows +cruce +crude +cruel +cruet +crumb +cruse +crush +crust +cryer +crypt +cuban +cubby +cubed +cubes +cubic +cubit +cuffs +culls +culpa +culta +cults +cumin +cupid +curae +curat +curbs +curds +cured +cures +curia +curie +curio +curls +curly +curry +curse +curso +curve +curvy +cushy +cusps +cuter +cycle +cymru +cynic +cyril +cysts +czars +czech +dacca +daces +dacha +daddy +daffy +daily +dairy +daisy +dakar +dalek +dales +daley +dally +dames +damns +damps +dance +dandy +danes +danny +dante +dared +dares +darks +darns +darts +dated +dates +datum +daubs +daunt +david +davis +davit +dawns +dazed +dazes +dcvos +deals +dealt +deans +dears +death +debar +debby +debet +debit +debra +debts +debug +debut +decal +decay +decks +decor +decoy +decry +deeds +deems +deeps +deere +defer +defoe +defog +degas +deify +deign +deism +deist +deity +delay +delft +delhi +delis +dells +delta +delve +demob +demon +demos +demur +dends +denim +denis +dense +dente +dents +depot +depth +derby +derek +derma +derry +desks +deter +deuce +devil +devon +dewar +dewed +dhabi +dhaka +dials +diana +diane +diary +diced +dicer +dices +dicey +dicit +dicks +dicky +dicta +diego +diets +digit +dijon +dikes +dilli +dills +dilly +dimes +dimly +dinar +dined +diner +dines +dingo +dings +dingy +dinky +dints +diode +direr +dirge +dirty +disco +discs +dishy +disks +ditch +ditto +ditty +divan +divas +dived +diver +dives +divot +divvy +dixie +dixit +dixon +dizzy +docks +dodge +dodgy +dodos +doers +doffs +doggo +doggy +dogma +doily +doing +dolby +doled +doles +dolls +dolly +dolor +dolts +domed +domes +domus +donee +donis +donna +donor +donut +dooms +doone +doors +doped +doper +dopes +dopey +doric +doris +dorms +dorsa +dosed +doses +dotal +doted +dotes +dotis +dotty +doubt +dough +douns +douse +dover +doves +dowdy +dowel +dower +dowle +downs +downy +dowry +dowse +doyen +doyle +dozed +dozen +dozes +drabs +draco +draff +draft +drags +drain +drake +drama +drams +drank +drape +drawl +drawn +draws +drays +dread +dream +dregs +dress +dribs +dried +drier +dries +drift +drill +drily +drink +drips +drive +droit +droll +drone +drool +droop +drops +dross +drove +drown +drubs +drugs +druid +drums +drunk +drupe +drury +dryad +dryer +dryly +dubai +ducal +ducat +duces +duchy +ducks +ducky +ducts +dudes +duels +duets +duffs +dukes +dulls +dully +dumas +dummy +dumps +dumpy +dunce +dunes +dunks +duped +dupes +duple +durst +durum +dusky +dusts +dusty +dutch +duvet +dwarf +dwell +dwelt +dwyer +dyads +dyers +dyfed +dying +dykes +dylan +dynes +eadem +eager +eagle +eared +earls +early +earns +earth +eased +easel +eases +eaten +eater +eaton +eaves +ebbed +ebony +eclat +edale +edema +edgar +edged +edges +edict +edify +edith +edits +educe +edwin +eerie +egged +egret +egypt +eider +eiger +eight +eigne +eject +eking +eland +elate +elbow +elder +elect +elegy +elfin +elgar +elgin +elias +elide +eliot +elise +elite +ellen +ellis +elope +elsie +elton +elude +elute +elves +elvis +emacs +embed +ember +emcee +emend +emery +emile +emily +emirs +emits +emote +empty +enact +ended +endow +endue +enema +enemy +enjoy +ennui +enoch +enrol +ensue +enter +entia +entry +enure +envoi +envoy +eosin +epees +epics +epoch +epode +epoxy +epsom +epson +equal +equip +erase +erect +ergot +erica +erith +ernie +ernst +erode +erred +errol +error +eruct +erupt +erwin +esher +esker +essay +essen +essex +ester +estop +ethel +ether +ethic +ethos +ethyl +etude +euros +evade +evans +evens +event +every +evict +evils +evoke +ewage +ewell +ewers +exact +exall +exalt +exams +excel +exeat +execs +exert +exile +exist +exits +expel +extol +extra +exude +exult +exxon +eying +eyres +eyrie +faber +fable +faced +facer +faces +facet +facie +facti +facto +facts +faddy +faded +fades +fagot +fails +faint +faire +fairs +fairy +faith +faits +faked +faker +fakes +fakir +falls +false +falsi +famed +fancy +fangs +fanny +farad +farce +fared +fares +farms +faros +farts +fasts +fatal +fated +fates +fatty +fatua +fault +fauna +fauns +faust +favor +fawns +faxed +faxes +fazed +fazes +fears +feast +feats +fecal +feces +fecit +feeds +feels +feign +feint +felix +fells +felon +felts +femes +femme +femur +fence +fends +feods +ferae +feral +feria +fermi +ferms +ferns +ferro +ferry +festa +fetal +fetch +feted +fetes +fetid +fetus +feuds +fever +fewer +fiats +fiber +fibre +fiche +fidei +fides +fiefs +field +fiend +fieri +fiery +fifes +fifth +fifty +fight +filch +filed +filer +files +filet +filey +fills +filly +films +filmy +filth +filum +final +finch +finds +fined +finer +fines +finks +finns +finny +fiord +fired +fires +firms +first +firth +fiscs +fishy +fists +fitch +fiver +fives +fixed +fixer +fixes +fizzy +fjord +flack +flaco +flags +flail +flair +flake +flaky +flame +flank +flans +flaps +flare +flash +flask +flats +flaws +flays +fleas +fleck +flees +fleet +flesh +fleta +flick +flier +flies +fling +flint +flips +flirt +flits +float +flock +flocs +floes +flogs +flood +floor +flops +flora +floss +flour +flout +flown +flows +flubs +flues +fluff +fluid +fluke +fluky +flume +flung +flunk +flush +flute +flyby +flyer +flyma +flynn +foals +foams +foamy +focal +focus +foeti +fogey +foggy +foils +foist +folds +folic +folio +folks +folly +fonts +foods +fools +foots +foray +force +fords +forge +forgo +foris +forks +forma +forms +forte +forth +forts +forty +forum +fosse +fouls +found +fount +fours +fovea +fowey +fowls +foxed +foxes +foyer +foyle +frail +frais +frame +franc +frank +fraud +frays +freak +freda +freed +freer +frees +freon +fresh +freta +frets +freud +friar +fried +fries +frill +frisk +fritz +frizz +frock +frogs +frome +frond +front +frost +froth +frown +froze +fruit +frump +fryer +fuchs +fucks +fudge +fuels +fugal +fugam +fugue +fully +fumed +fumes +fundi +funds +fungi +funks +funky +funny +fuqua +furls +furor +furry +furta +furze +fused +fusel +fuser +fuses +fussy +fusty +futon +fuzes +fuzzy +gabby +gable +gabon +gaels +gaffe +gaffs +gafol +gager +gages +gaily +gains +gaits +gaius +galas +gales +galls +gamed +games +gamin +gamma +gamut +gangs +gaols +gaped +gapes +garbs +garth +gases +gasps +gassy +gated +gates +gaudy +gauge +gault +gaunt +gauss +gauze +gauzy +gavel +gavin +gawks +gawky +gayer +gayle +gazed +gazer +gazes +gears +gecko +geese +gelds +gelid +gemot +genes +genet +genie +genii +genoa +genre +gents +genus +geode +geoff +germs +gerry +gesso +getup +ghana +ghent +ghost +ghoul +giant +gibbs +gibed +gibes +giddy +gifts +gigot +gigue +gilds +giles +gills +gimme +gimps +gimpy +gipsy +girds +girls +giros +girth +gismo +given +giver +gives +gizmo +glade +gland +glare +glass +glaze +gleam +glean +glees +glenn +glens +glide +glint +gloat +globe +globs +gloms +gloom +glory +gloss +glove +glows +glued +glues +gluey +gluon +gluts +glyph +gnarl +gnash +gnats +gnaws +gnome +goads +goals +goats +godly +goers +gofer +gogol +going +golan +golfs +golly +gonad +goner +gongs +goods +goody +gooey +goofs +goofy +gooks +goole +goons +goose +gored +gores +gorge +gorse +gouda +gouge +gourd +gouts +gouty +govan +gower +gowns +grabs +grace +grade +grads +graft +grail +grain +grams +grand +grant +grape +graph +grasp +grass +grata +grate +grave +gravy +grays +graze +great +grebe +greed +greek +green +greet +greta +greve +greys +grids +grief +grieg +griff +grill +grime +grimm +grimy +grind +grins +gripe +grips +grist +grits +groan +groat +groin +groom +grope +gross +group +grout +grove +growl +grown +grows +grubs +gruel +gruff +grump +grunt +guano +guard +guars +guava +gucci +guess +guest +guide +guild +guile +guilt +guise +gulag +gulch +gulfs +gulls +gully +gulps +gumbo +gummy +gunge +gungy +gunny +guppy +gurus +gushy +gusto +gusts +gusty +gutsy +guyed +gwent +gypsy +gyred +gyres +gyros +gyves +habeo +habet +habit +hable +hacks +hades +hafts +hague +haifa +haiku +hails +hairs +hairy +haiti +hakes +halal +hales +haley +hallo +halls +halos +halts +halve +hammy +hands +handy +hangs +hanks +hanky +hanna +hanoi +hanse +haply +happy +hardy +hared +harem +hares +harks +harms +harps +harpy +harry +harsh +harts +hasid +hasps +haste +hasty +hatch +hated +hater +hates +haugh +hauls +haunt +haute +haven +haves +havoc +hawed +hawes +hawks +hawse +haydn +hayed +hayes +hazed +hazel +hazes +heads +heady +heals +heaps +heard +hears +heart +heath +heats +heave +heavy +hecto +hedge +heeds +heels +hefts +hefty +heinz +heirs +heist +helen +helga +helix +hello +hells +helms +helot +helps +hence +henge +henna +henry +herbs +herds +heres +herne +heron +hertz +hetty +hewed +hewer +hexed +hexes +hicks +hides +highs +hiked +hiker +hikes +hilda +hills +hilly +hilts +hindi +hinds +hindu +hinge +hints +hippo +hippy +hired +hirer +hires +hitch +hives +hoard +hoary +hobby +hobos +hocks +hogan +hoist +hokum +holds +holed +holes +holly +holst +homed +homer +homes +homey +homme +honda +honed +hones +honey +honks +honky +honor +hooch +hoods +hooey +hoofs +hooks +hooky +hoops +hoots +hoped +hopes +hopis +horae +horde +horns +horny +horse +horsy +hosea +hosed +hoses +hosts +hotel +hotly +hough +hound +hours +house +hovel +hover +howdy +howls +hubby +huffs +huffy +hulas +hulks +hullo +hulls +human +humid +humor +humph +humps +humus +hunch +hunks +hunts +hurls +huron +hurry +hurst +hurts +husks +husky +hussy +hutch +hydra +hydro +hyena +hymen +hymns +hyoid +hyped +hyper +hypes +hypos +hyrax +hythe +iambs +ibiza +ibsen +icier +icily +icing +icons +idaho +ideal +ideas +idees +idiom +idiot +idled +idler +idles +idols +idris +idyll +idyls +ieuan +igloo +ikbal +ikons +ileac +ileum +iliac +iliad +illud +image +imago +imams +imbed +imbue +immix +impel +imply +inane +inapt +incas +incur +index +india +indus +inept +inert +infer +infix +infra +ingot +inked +inlay +inlet +inner +input +inset +intel +inter +intol +intra +intro +inuit +inure +ionic +iraqi +irate +irene +irish +irked +irons +irony +irvin +irwin +isaac +isbns +islam +islay +isles +islet +issue +italy +itchy +items +ivied +ivies +ivory +jabot +jacks +jacob +jaded +jades +jaffa +jails +jambs +james +jamey +jamie +jammy +janet +janus +japan +japed +japer +japes +jason +jaunt +jawed +jazzy +jeans +jeeps +jeers +jelly +jemmy +jenny +jerks +jerky +jerry +jesse +jests +jesus +jetty +jewel +jewry +jibed +jibes +jidda +jiffy +jihad +jilts +jimmy +jingo +jinks +jinni +jived +jives +jocks +johns +joins +joint +joist +joked +joker +jokes +jokey +jolly +jolts +jonah +jones +joule +jours +joust +jowls +joyce +judas +judea +judge +judos +juges +juice +juicy +jujus +jukes +julep +jules +julia +julie +julys +jumbo +jumps +jumpy +junco +junes +junks +junky +junta +junto +jural +jurat +juris +juror +juste +kabob +kabul +kafka +kakis +kaman +kapok +kappa +kaput +karat +karen +karma +kasha +kathy +katie +kauai +kayak +kayla +kayos +kazoo +kbyte +keats +kebab +kebob +keels +keens +keeps +keith +kelly +kelps +kelso +kenny +kenos +kenya +kepis +kerbs +kerry +ketch +kevin +keyed +keyus +khaki +khans +khmer +kicks +kills +kilns +kilos +kilts +kinds +kings +kinks +kinky +kiosk +kited +kites +kitts +kitty +kiwis +klaus +klein +klieg +klutz +knack +knave +knead +kneed +kneel +knees +knell +knelt +knife +knish +knits +knobs +knock +knoll +knots +known +knows +knurl +koala +kodak +kolas +kooks +kooky +koran +korea +korma +kraal +kraft +kraut +krill +krona +krone +kuala +kudos +kudzu +kurds +kyoto +label +labia +labor +laced +lacer +laces +lacey +lacks +lacta +laded +laden +lades +ladle +laesa +lager +lagos +laica +laird +lairs +laity +lakes +lamas +lambs +lamed +lamer +lames +lamps +lanai +lance +lands +lanes +lanka +lanky +laois +lapel +lapis +lapse +larch +lards +large +largo +larks +larne +larry +larva +laser +lasso +lasts +latch +later +latex +lathe +laths +latin +laude +lauds +laugh +laura +laved +laves +lawns +laxly +layer +lazed +lazes +leach +leads +leafs +leafy +leaks +leaky +leans +leant +leaps +leapt +learn +lease +leash +least +leave +ledge +leduc +leech +leeds +leeks +leers +leery +leets +lefts +lefty +legal +legem +leges +leggy +legit +legum +leigh +leith +lemma +lemon +lemur +lends +lenin +lenny +lento +leper +leroy +lessa +letup +levee +level +lever +levin +levis +lewes +lewis +lhasa +liana +liars +libel +liber +libra +libre +libya +licet +licit +licks +liege +liens +lifer +lifts +light +liked +liken +likes +lilac +lilly +lilts +limas +limbo +limbs +limed +limes +limey +limit +limns +limos +limps +linda +lined +linen +liner +lines +lingo +links +lions +lipid +liras +lisle +lisps +lists +liszt +litem +liter +lithe +litho +litis +litre +lived +liven +liver +lives +livid +llama +lleyn +lloyd +loads +loafs +loamy +loans +loath +lobar +lobby +lobed +lobes +lobos +local +lochs +locks +locos +locum +locus +lodes +lodge +loess +lofts +lofty +loges +logic +logos +loins +loire +lolls +lolly +loner +longs +loofa +looks +looms +loons +loony +loops +loopy +loose +loots +loped +lopes +loral +loran +lords +lorna +lorry +loser +loses +lotto +lotus +lough +louie +louis +loupe +lours +louse +lousy +louth +louts +loved +lover +loves +lowed +lower +lowly +lowry +loyal +lrams +luaus +lucas +lucia +lucid +lucks +lucky +lucre +ludic +luger +lulls +lulus +lumen +lumps +lumpy +lunar +lunch +lundy +lunge +lungs +lupin +lupus +lurch +lured +lures +lurid +lurks +lusts +lusty +lutes +luton +luzon +lydia +lying +lymph +lynch +lynne +lyons +lyres +lyric +lysol +mabel +macao +macaw +maces +macho +macro +madam +madge +madly +mafia +magic +magma +magna +magus +maids +mails +maims +maine +mains +mainz +maize +major +maker +makes +malay +males +malls +malta +malts +malty +malum +mamas +mamba +mambo +mamma +mammy +manes +mange +mango +mangy +mania +manic +manly +manna +manor +manse +manta +manus +maori +maple +march +marco +mardi +mares +margb +marge +margl +margo +margr +margt +maria +marie +mario +maris +marks +marls +marry +marsh +marts +maser +masks +mason +massa +masse +massy +masts +match +mated +mater +mates +matey +maths +matte +matzo +mauls +mauna +mauve +maven +mavis +maxim +maxis +mayan +mayas +maybe +mayor +mazda +mazes +mccoy +mcgee +mckay +mckee +meals +mealy +means +meant +meany +meath +meats +meaty +mecca +mecum +medal +media +medic +medoc +meets +megan +melba +melds +melee +melon +melts +memos +mends +mensa +mente +menus +meows +merck +mercy +merge +merit +merle +merry +mesas +mesne +meson +messy +metal +meted +meter +metes +meths +metre +metro +metus +mewed +mewls +mezzo +miami +miaow +micah +micas +micky +micro +midas +middy +midge +midis +midst +miens +miffs +might +mikes +milan +milch +miler +miles +milks +milky +milli +mills +milne +milts +mimed +mimes +mimic +minas +mince +minds +mined +miner +mines +minim +minis +minks +minor +minsk +mints +minty +minus +mired +mires +mirth +miser +mises +missy +mists +misty +mites +mitre +mitts +mixed +mixer +mixes +moans +moats +mobil +mocha +mocks +modal +model +modem +modes +modus +mogul +moils +moir� +moist +molar +molds +moldy +moles +molls +molly +molts +momma +mommy +monad +monet +money +monks +month +monty +mooch +moods +moody +mooed +moons +moony +moore +moors +moose +moots +moped +mopes +moral +moray +morel +mores +morns +moron +morse +moses +mosey +mossy +motel +motes +motet +moths +motif +motor +motto +moues +mould +moult +mound +mount +mourn +mouse +mousy +mouth +moved +mover +moves +movie +mowed +mower +mucks +mucky +mucus +muddy +muffs +mufti +muggy +mulch +mulct +mules +mulls +multa +multi +mumbo +mummy +mumps +munch +munro +mural +murex +murky +mused +muses +mushy +music +musky +musts +musty +muted +mutes +mutts +muzak +muzzy +mynah +myrrh +myths +naafi +nabob +nacho +nacre +nadir +naffs +naiad +nails +nairn +naive +na�fs +naked +named +names +nancy +nanny +naomi +napes +nappy +narks +narrs +nasal +nasty +natal +natty +naval +navel +naves +navvy +nazis +neagh +neaps +nears +neath +necks +needs +needy +negev +negro +nehru +neigh +nepal +nerds +nerdy +nerve +nervy +nests +never +nevil +nevis +nevus +newel +newer +newly +newsy +newts +nexus +nicer +niche +nicks +niece +nifty +nigel +niger +night +nihil +nikes +nimbi +nines +ninny +ninth +nippy +nisei +nitre +nitro +nitty +nixes +nixon +nobel +nobis +noble +nobly +nodal +noddy +nodes +noels +noire +noise +noisy +nolle +nomad +nomen +nonce +nones +nooks +noose +norma +norms +norse +north +nosed +noses +nosey +notae +notch +noted +notes +nouns +novae +novas +novel +novum +novus +nspcc +nudes +nudge +nudum +nuked +nukes +nulla +nulle +nulli +nulls +numbs +nurse +nutty +nylon +nymph +oaken +oakum +oared +oases +oasis +oaten +oaths +obese +obeys +obits +objet +oboes +occur +ocean +ochre +octal +octet +odder +oddly +odeon +odium +odour +offal +offer +often +ogees +ogled +ogles +ogres +oiled +oiler +okapi +okays +okras +olden +older +oldie +oleic +oleos +olive +omagh +omaha +omega +omens +omits +omnes +omnia +omnis +onere +ongar +onion +onset +oohed +oomph +oozed +oozes +opals +opens +opera +opine +opium +opted +optic +orals +orate +orbit +order +organ +orion +ormuz +osaka +oscar +osier +other +otter +ought +ouija +ounce +ousts +outdo +outer +outgo +outre +outr� +ouzel +ovals +ovary +ovate +ovens +overs +overt +ovine +ovoid +ovule +owing +owlet +owned +owner +oxeye +oxfam +oxide +oxlip +oyers +ozone +pablo +paced +pacer +paces +packs +pacts +paddy +padre +paean +pagan +paged +pager +pages +paige +pails +pains +paint +pairs +paled +paler +pales +palls +palms +palsy +panda +paned +panel +panes +pangs +panic +panky +pansy +pants +panty +papal +papas +papaw +paper +papua +parch +pared +pares +paria +paris +parka +parks +parol +parry +parse +parte +parts +party +parva +pasha +pass� +passu +pasta +paste +pasts +pasty +patch +paten +pater +pates +paths +patio +patna +patsy +patty +paula +paulo +pause +paved +paves +pawed +pawls +pawns +payee +payer +payne +peace +peach +peaks +peaky +peals +pearl +pears +pease +peaty +pecan +pecks +pedal +pedis +peeks +peels +peens +peeps +peers +peeve +peggy +peine +pekoe +pelts +penal +pence +pends +penge +penis +penny +pensa +peons +peony +peppy +pepsi +pepys +perch +percy +perez +peril +perks +perky +perms +perry +perth +perts +pesky +pesos +pests +petal +peter +petit +petty +pewee +pewit +phase +phial +phlox +phnom +phone +phony +photo +phyla +piano +picas +picks +picky +picot +picts +piece +piers +pieta +piety +piggy +pigmy +piker +pikes +pilaf +pilau +piled +piles +pills +pilot +pimps +pinch +pined +pines +pings +pinks +pinky +pinto +pints +pinup +pious +piped +piper +pipes +pipit +pique +piste +pitch +piths +pithy +piton +pitta +pivot +pixel +pixie +pizza +place +plaid +plain +plait +plane +plank +plans +plant +plash +plate +plato +plats +platt +platy +playa +plays +plaza +plead +pleas +pleat +plebe +plebs +plena +plied +plies +plink +pliny +plods +plonk +plops +plots +ploys +pluck +plugs +plumb +plume +plump +plums +plumy +plunk +plush +pluto +poach +pocks +podge +podgy +podia +poems +poesy +poets +point +poise +poked +poker +pokes +polar +poled +poles +polio +polka +polls +polly +polyp +ponce +ponds +ponit +pooch +poole +pools +poona +poops +popes +poppy +porch +pored +pores +porgy +porno +ports +posed +poser +poses +posit +posse +posts +potty +pouch +poufs +pound +pours +pouts +power +powys +poxes +praia +prams +prang +prank +prate +pratt +prawn +prays +prece +preen +preps +press +preys +price +prick +pride +pried +prier +pries +prigs +prima +prime +primp +print +prior +prise +prism +prius +privy +prize +probe +prods +proem +prole +promo +proms +prone +prong +proof +props +prose +prosy +proud +prove +provo +prowl +prows +proxy +prude +prune +psalm +psion +psych +pubes +pubic +pubis +pucks +puffs +puffy +puked +pukes +pukka +puled +pules +pulls +pulps +pulpy +pulse +pumas +pumps +punch +punic +punks +punts +pupae +pupal +pupas +pupil +puppy +puree +purer +purge +purim +puris +purls +purrs +purse +pushy +pussy +putts +putty +pygmy +pylon +pyres +pyrex +qatar +quack +quads +quaff +quail +quake +quaky +qualm +quare +quark +quart +quash +quasi +quays +queen +queer +quell +quern +query +quest +queue +quick +quids +quiet +quiff +quill +quilt +quint +quips +quire +quirk +quirt +quite +quito +quits +quoad +quoin +quoit +quota +quote +quoth +rabat +rabbi +rabid +raced +racer +races +racks +radar +radii +radio +radix +radon +rafts +ragas +raged +rages +raids +rails +rains +rainy +raise +rajah +rajas +raked +rakes +rally +ralph +ramie +ramps +ranch +rands +randy +range +ranks +rants +raped +rapes +rapid +rarer +rased +rases +rasps +raspy +rasta +ratam +rated +rates +ratio +ratty +raved +ravel +raven +raver +raves +rawer +rayed +rayon +razed +razes +razor +reach +react +reads +ready +realm +reams +reaps +rearm +rears +rebel +rebus +rebut +recap +recht +recks +recta +recti +recto +recur +redid +reeds +reedy +reefs +reeks +reels +reeve +refer +refit +regal +regan +regii +regis +regni +reich +reify +reign +reims +reins +reits +rejig +relax +relay +relic +remit +remus +renal +rends +renee +renew +rents +repay +repel +reply +repos +reran +rerum +rerun +resat +reset +resin +resit +rests +retch +retie +retro +retry +rette +reuse +revel +revue +rheas +rheum +rhine +rhino +rhode +rhone +rhyme +rials +rican +ricer +riche +ricks +ricky +rider +rides +ridge +rifer +rifle +rifts +right +rigid +rigor +riled +riles +riley +rills +rimed +rimes +rinds +rings +rinks +rinse +riots +ripen +riper +ripon +risen +riser +rises +risks +risky +rites +ritzy +rival +rived +riven +river +rives +rivet +riyal +roach +roads +roams +roans +roars +roast +robed +robes +robin +robot +rocks +rocky +rodeo +rodin +roger +rogue +roils +roles +rolls +roman +romeo +romps +rondo +roods +roofs +rooks +rooms +roomy +roost +roots +roped +roper +ropes +ropey +rorer +roses +rosin +rotas +rotes +rotor +rouen +rou�s +rouge +rough +round +rouse +roust +route +routs +roved +rover +roves +rowan +rowdy +rowed +rowel +rower +royal +royce +rspca +rubes +ruble +ruche +rucks +ruddy +ruder +ruffs +rufus +rugby +ruing +ruins +ruled +ruler +rules +rumba +rumen +rummy +rumor +rumps +runes +rungs +runic +runny +runts +rupee +rural +ruses +rusks +rusts +rusty +rutty +saabs +saber +sable +sabot +sabre +sacci +sacks +sacra +sadie +sadly +safer +safes +sagas +sager +sages +sahib +sails +saint +sakes +salad +salem +sales +salic +sally +salmi +salon +salop +salsa +salts +salty +salus +salve +salvo +samba +sammy +samoa +sands +sandy +saner +santa +santo +sappy +sarah +saran +saris +sassy +satan +sated +sates +satin +satre +satyr +sauce +saucy +saudi +sauna +saut� +saved +saver +saves +savor +savoy +savvy +sawed +saxes +saxon +scabs +scads +scald +scale +scalp +scaly +scamp +scams +scans +scant +scare +scarf +scarp +scars +scary +scats +scene +scent +schwa +scion +scire +scite +scoff +scold +scone +scoop +scoot +scope +score +scorn +scots +scott +scour +scout +scowl +scows +scram +scrap +scree +screw +scrim +scrip +scrod +scrub +scrum +scuba +scuds +scuff +scull +scups +scurf +seals +seams +seamy +sears +seato +seats +sebum +sects +secus +sedan +seder +sedge +sedum +seeds +seedy +seeks +seems +seeps +seers +segos +segue +seign +seiko +seine +seisi +seism +seize +selby +sells +semen +sends +senna +sense +seoul +sepal +sepia +septa +serbs +serfs +serge +serif +serum +serve +servo +setae +seven +sever +sewed +sewer +sexed +sexes +shack +shade +shads +shady +shaft +shags +shahs +shake +shako +shaky +shale +shall +shalt +shame +shams +shane +shank +shape +shard +share +shark +sharp +shaun +shave +shawl +shawn +shays +sheaf +shear +sheba +sheds +sheen +sheep +sheer +sheet +sheik +shelf +shell +shied +shier +shies +shift +shill +shims +shine +shins +shiny +ships +shire +shirk +shirr +shirt +shish +shits +shiva +shoal +shoat +shock +shoed +shoes +shoji +shone +shook +shoos +shoot +shops +shore +shorn +short +shots +shout +shove +shown +shows +showy +shred +shrew +shrub +shrug +shuck +shuns +shunt +shush +shuts +shyer +shyly +sibyl +sided +sides +sidle +siege +sieve +sifts +sighs +sight +sigma +signa +signs +sikhs +silas +silks +silky +sills +silly +silos +silts +silty +simon +simul +sinai +since +sinew +singe +singh +sings +sinks +sinus +sioux +sired +siren +sires +sisal +sissy +sitae +sitar +sited +sites +situs +sixes +sixth +sixty +sized +sizes +skald +skate +skeet +skein +skews +skids +skied +skier +skies +skiff +skill +skimp +skims +skink +skins +skips +skirl +skirt +skits +skive +skuas +skulk +skull +skunk +slabs +slack +slags +slain +slake +slams +slang +slant +slaps +slash +slate +slats +slave +slavs +slaws +slays +sleds +sleek +sleep +sleet +slept +slice +slick +slide +slier +sligo +slime +slims +slimy +sling +slink +slips +slits +slobs +sloes +slogs +sloop +slope +slops +slosh +sloth +slots +slows +slued +slues +slugs +slump +slums +slung +slunk +slurp +slurs +slush +sluts +slyer +slyly +smack +small +smart +smash +smear +smell +smelt +smile +smirk +smite +smith +smock +smoke +smoky +smote +smuts +snack +snafu +snags +snail +snake +snaky +snaps +snare +snarl +sneak +sneer +snick +snide +sniff +snipe +snips +snits +snobs +snood +snook +snoop +snore +snort +snots +snout +snows +snowy +snubs +snuck +snuff +soaks +soaps +soapy +soars +soave +sober +socks +sodas +sodom +sofas +sofia +softy +soggy +soils +solar +soled +soles +solet +solid +solis +solos +solum +solve +somas +somme +sonar +songs +sonic +sonny +sonya +sooth +sooty +soppy +sorbs +sorer +sores +sorry +sorts +sough +souks +souls +sound +soups +soupy +sours +souse +south +sowed +sower +space +spade +spain +spank +spans +spare +spark +spars +spasm +spate +spats +spawn +spays +speak +spear +speck +specs +speed +spell +spelt +spend +spent +sperm +spews +spice +spick +spicy +spied +spiel +spies +spike +spiky +spill +spilt +spine +spins +spiny +spire +spite +spits +spivs +splat +splay +split +spoil +spoke +spoof +spook +spool +spoon +spoor +spore +sport +spots +spout +sprat +spray +spree +sprig +sprit +spuds +spume +spunk +spurn +spurs +spurt +sputa +squab +squad +squat +squaw +squib +squid +stabs +stack +staff +stage +stags +stagy +staid +stain +stair +stake +stale +stalk +stall +stamp +stand +stank +stare +stark +stars +start +stash +state +stave +stays +stead +steak +steal +steam +steed +steel +steep +steer +stein +stele +stems +steno +steps +stern +stets +steve +stews +stick +sties +stiff +stile +still +stilt +sting +stink +stint +stirs +stoat +stock +stoic +stoke +stole +stoma +stomp +stone +stony +stood +stool +stoop +stops +store +stork +storm +story +stoup +stour +stout +stove +stowe +stows +strap +straw +stray +strew +strip +strop +strum +strut +stubs +stuck +studs +study +stuff +stump +stung +stunk +stuns +stunt +styes +style +styli +suave +sucks +sudan +sudsy +suede +sufic +sufis +sugar +suing +suite +suits +sulfa +sulks +sulky +sully +sumac +summa +sumps +sunni +sunny +sunup +super +supra +surds +surer +surfs +surge +surly +susan +sushi +susie +sutra +swabs +swage +swags +swain +swami +swamp +swank +swans +swaps +sward +swarm +swath +swats +sways +swazi +swear +sweat +swede +sweep +sweet +swell +swept +swift +swigs +swill +swims +swine +swing +swipe +swirl +swish +swiss +swoon +swoop +swops +sword +swore +sworn +swots +swung +sybil +sykes +sylph +synch +synod +synth +syria +syrup +tabby +table +taboo +tabor +tacit +tacks +tacky +tacos +taffy +taiga +tails +taint +taken +taker +takes +talas +tales +talks +talky +tally +talon +tamed +tamer +tames +tamil +tammy +tampa +tamps +tango +tangs +tangy +tanks +tansy +tanya +taped +taper +tapes +tapir +tardy +tares +tarns +tarok +taros +tarot +tarps +tarry +tarsi +tarts +tasks +taste +tasty +tatty +taunt +taupe +tawny +taxed +taxes +taxis +teach +teaks +teals +teams +tears +teary +tease +teats +tecum +teddy +teems +teens +teeny +teeth +teign +telex +tells +telly +tempi +tempo +temps +tempt +tenby +tench +tends +tenet +tenon +tenor +tense +tenth +tents +tepee +tepid +terms +terns +terra +terry +terse +teste +tests +testy +tetra +texan +texas +texts +thane +thank +thaws +theca +theft +their +theme +there +therm +these +theta +thick +thief +thigh +thine +thing +think +thins +third +thong +thorn +those +three +threw +throb +throe +throw +thrum +thuds +thugs +thumb +thump +thyme +tiara +tiber +tibet +tibia +ticks +tidal +tided +tides +tiers +tiffs +tiger +tight +tikes +tilde +tiled +tiler +tiles +tills +tilth +tilts +timed +timer +times +timet +timex +timid +timmy +timor +tined +tines +tinge +tinny +tints +tipsy +tired +tiree +tires +tirol +titan +tithe +title +titre +titus +tizzy +toads +toady +toast +today +toddy +toffs +togas +toile +toils +token +tokyo +tolls +tombs +tomes +tommy +tonal +tondo +toned +toner +tones +tonga +tongs +tonic +tonne +tools +tooth +toots +topaz +toped +toper +topes +topic +topsy +toque +torah +torch +torso +torte +torts +tosca +tosco +total +toted +totem +totes +touch +tough +tours +touts +towed +towel +tower +towns +towyn +toxic +toxin +toyed +trace +track +tract +tracy +trade +trail +train +trait +tramp +trams +trans +traps +trash +trawl +trays +tread +treat +treed +trees +treks +trend +trent +tress +trews +treys +triad +trial +tribe +trice +trick +tried +trier +tries +trigs +trill +trims +trine +trior +trios +tripe +trips +trite +troll +tromp +troon +troop +trope +troth +trots +trout +trove +truce +truck +trudy +trued +truer +trues +truly +trump +trunk +truro +truss +trust +truth +tryst +tsars +tubas +tubby +tuber +tubes +tucks +tudor +tuffs +tufts +tulip +tulle +tumid +tummy +tumor +tunas +tuned +tuner +tunes +tunic +tunis +tunny +turbo +turfs +turin +turks +turns +turps +turvy +tusks +tutee +tutor +tutus +tuxes +twain +twang +tweak +tweed +tweet +twerp +twice +twigs +twill +twine +twins +twirl +twist +twits +twixt +tying +tykes +tyler +typed +types +typos +tyres +tyrol +tyros +tyson +tzars +udder +ukaea +ukase +ulcer +ulnae +ulnas +ultra +umber +umbra +unapt +unarm +unbar +uncap +uncle +uncut +under +undid +undue +unfed +unfit +uniat +unify +union +unite +units +unity +unius +unlit +unman +unmet +unpeg +unpin +unsay +unsex +untie +until +unwed +unzip +upend +upped +upper +upset +upton +urban +ureic +urged +urges +uriah +urine +usage +users +usher +using +usual +usurp +usury +uteri +utica +utile +utter +uvula +uzbek +vacua +vaduz +vague +vales +valet +valid +valor +value +valve +vamps +vance +vanes +vapid +vapor +vases +vatic +vault +vaunt +veers +vegan +vegas +veies +veils +veins +velar +veldt +velum +venal +vends +venia +venom +vents +venue +venus +veray +verba +verbs +verde +verdi +verge +versa +verse +verso +verus +verve +vests +vetch +vexed +vexes +vials +viand +vibes +vicar +vices +vichy +vicki +video +views +vigil +vigor +viler +villa +villi +vines +vinyl +viola +viols +viper +viral +vireo +vires +virge +virgo +virus +visas +visit +visne +visor +vista +visus +vitae +vital +vitas +vitro +vitus +vivid +vivos +vivre +vivum +vixen +vizor +vocal +vodka +vogue +voice +voids +voile +voles +volga +volta +volts +volvo +vomit +voted +voter +votes +vouch +vowed +vowel +vroom +vulva +vying +wacky +waded +wader +wades +wafer +wafts +waged +wager +wages +wagon +waifs +wails +waist +waite +waits +waive +waked +waken +wakes +waldo +wales +walks +walls +wally +waltz +wands +waned +wanes +wanly +wants +wards +wares +warms +warns +warps +warts +warty +washy +wasps +waste +watch +water +watts +waugh +waved +waver +waves +waxed +waxen +waxes +wayne +weald +weals +weans +wears +weary +weave +weber +wedge +weeds +weedy +weeks +weeny +weeps +weepy +wefts +weigh +weird +weirs +welch +welds +wells +welsh +welts +wench +wends +wendy +wetly +whack +whale +whams +wharf +wheat +wheel +whelk +whelp +where +whets +which +whiff +whigs +while +whims +whine +whiny +whips +whirl +whirr +whisk +whist +white +whizz +whole +whoop +whops +whore +whorl +whose +wicks +widen +wider +widow +width +wield +wigan +wight +wilde +wilds +wiles +wills +willy +wilma +wilts +wimps +wimpy +wince +winch +winds +windy +wined +wines +wings +winks +winos +wiped +wiper +wipes +wired +wires +wised +wiser +wises +wishy +wisps +wispy +witam +witch +witco +witty +wives +wizen +woken +wolds +wolfe +wolff +wolfs +woman +wombs +women +wonky +woods +woody +wooed +wooer +woofs +woozy +words +wordy +works +world +worms +wormy +worry +worse +worst +worth +would +wound +woven +wowed +wrack +wraps +wrath +wreak +wreck +wrens +wrest +wrier +wring +wrist +write +writs +wrong +wrote +wroth +wrung +wryer +wryly +wyatt +wyman +xebec +xenon +xerox +xviii +xxiii +xxvii +xylem +yacht +yahoo +yalta +yanks +yards +yarns +yawed +yawls +yawns +yearn +years +yeast +yeats +yells +yelps +yemen +yenta +yetis +yield +yodel +yogis +yoked +yokel +yokes +yolks +yolky +young +yours +youth +yowls +yoyos +ypres +yuans +yucca +yukon +yummy +zaire +zebra +zebus +zeiss +zeros +zesty +zilch +zings +zippy +zloty +zoned +zones +zooms +zulus +zunis +�clat \ No newline at end of file diff --git a/app/lib/core/const/color_constants.dart b/app/lib/core/const/color_constants.dart new file mode 100644 index 0000000..8cb5050 --- /dev/null +++ b/app/lib/core/const/color_constants.dart @@ -0,0 +1,11 @@ +import 'package:flutter/cupertino.dart'; + +class ColorConstants{ + static const Color primaryGreen = Color(0xFF21BC5F); + static const Color primaryOrange = Color(0xFFFE9F10); + static const Color primaryGrey = Color(0xFFDEDEDE); + static const Color primaryGreyLight = Color(0xFFF3F2F2); + static const Color primaryGreyMedium = Color(0xFFD1D5DB); + static const Color primaryGreenLight= Color(0xFFE1F4EB); + static const Color primaryRedLight = Color(0xFFF4E1E1); +} \ No newline at end of file diff --git a/app/lib/core/const/text_constants.dart b/app/lib/core/const/text_constants.dart new file mode 100644 index 0000000..e38e0a5 --- /dev/null +++ b/app/lib/core/const/text_constants.dart @@ -0,0 +1,17 @@ +class TextConstants { + static const String gameTitle = 'WORDLE'; + static const String errorWrongWord = "Слова нет в словаре"; + static const String errorWrongWordLength = "Длина слова не подходит"; + static const String youWin = "Вы победили!"; + static const String youLose = "Вы проиграли!"; + static const String howToPlayTitle = "Как играть"; + static const String howToPlayText = "Угадайте слово за 6 попыток\n\n" + "Каждая попытка должна быть существующим словом из 5-ти букв\n\n" + "После каждой попытки, цвет символов будет меняться, чтобы показать" + "насколько вы близки к загаданному слову"; + static const String howToPlayRole1 = "Таких букв в слове нет"; + static const String howToPlayRole2 = + "Буква есть в слове, но она не на своем месте"; + static const String howToPlayRole3 = "Буква на своем месте"; + static const String nextWordle = "Следующее слово через"; +} diff --git a/app/lib/core/data/data_singleton.dart b/app/lib/core/data/data_singleton.dart new file mode 100644 index 0000000..b4db387 --- /dev/null +++ b/app/lib/core/data/data_singleton.dart @@ -0,0 +1,138 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:guessing_words/core/const/text_constants.dart'; +import 'package:guessing_words/core/data/enums/keyboard_keys.dart'; +import 'package:guessing_words/core/data/enums/message_types.dart'; +import 'package:guessing_words/core/presentation/home/cubit/home_cubit.dart'; + +class DataSingleton { + static final DataSingleton _dataSingleton = DataSingleton._internal(); + Set allWords = {}; + String secretWord = ""; + List gridData = [""]; + Map coloredLetters = {}; + int currentWordIndex = 0; + + factory DataSingleton() { + return _dataSingleton; + } + + DataSingleton._internal() { + if (secretWord.isEmpty) { + createWord(); + } + } + + bool setLetter(KeyboardKeys key) { + if (KeyboardKeys.enter.name == key.name) { + return false; + } + if (gridData.length <= currentWordIndex) { + gridData.add(""); + } + if (gridData[currentWordIndex].length < 5) { + gridData[currentWordIndex] = gridData[currentWordIndex] + key.name; + return true; + } + return false; + } + + void removeLetter() { + if (gridData.length <= currentWordIndex) { + gridData.add(""); + } + int wordLength = gridData[currentWordIndex].length; + if (wordLength > 0) { + gridData[currentWordIndex] = + gridData[currentWordIndex].substring(0, wordLength - 1); + } + } + + HomeState submitWord() { + if (gridData.length <= currentWordIndex) { + gridData.add(""); + } + if (currentWordIndex < 5) { + if (gridData[currentWordIndex].length == 5) { + if (gridData[currentWordIndex] == secretWord) { + nextWord(); + return WinGameState(); + } + if (allWords.contains(gridData[currentWordIndex])) { + nextWord(); + return GridUpdateState(); + } else { + return SnackBarMessage( + MessageTypes.error, TextConstants.errorWrongWord); + } + } else { + return SnackBarMessage( + MessageTypes.error, TextConstants.errorWrongWordLength); + } + } else { + return LoseGameState(); + } + } + + void nextWord() { + final word = gridData[currentWordIndex]; + word.split("").asMap().map((key, value) { + if (secretWord[key] == value) { + //green + if (coloredLetters.containsKey(value)) { + coloredLetters.update(value, (value) => Colors.green); + } else { + coloredLetters.addAll({value: Colors.green}); + } + } else if (secretWord.contains(value)) { + //orange + if (coloredLetters.containsKey(value)) { + if (coloredLetters[key] == Colors.black38) { + coloredLetters.update(value, (value) => Colors.orangeAccent); + } + } else { + coloredLetters.addAll({value: Colors.orangeAccent}); + } + } else { + //grey + if (!coloredLetters.containsKey(value)) { + coloredLetters.addAll({value: Colors.black38}); + } + } + return MapEntry(key, value); + }); + if (currentWordIndex < 5) { + currentWordIndex++; + } + } + + Future createWord() async { + final words = (await rootBundle.loadString('assets/words.txt')).split("\n"); + var now = DateTime.now(); + var random = + Random(now.year * 10000 + now.month * 100 + now.day + now.hour + 1); + var index = random.nextInt(words.length); + secretWord = words[index]; + allWords = words.toSet(); + print(secretWord); + return secretWord; + } + + String getLetters() { + return gridData.join(); + } + + Color getKeyColor(KeyboardKeys myKey) { + return coloredLetters[myKey.name] ?? Colors.black26; + } + + void resetData() { + allWords = {}; + secretWord = ""; + gridData = [""]; + coloredLetters = {}; + currentWordIndex = 0; + } +} diff --git a/app/lib/core/data/enums/keyboard_keys.dart b/app/lib/core/data/enums/keyboard_keys.dart new file mode 100644 index 0000000..0409d0d --- /dev/null +++ b/app/lib/core/data/enums/keyboard_keys.dart @@ -0,0 +1,6 @@ +enum KeyboardKeys{ + q,w,e,r,t,y,u,i,o,p, + a,s,d,f,g,h,j,k,l, + z,x,c,v,b,n,m, + enter +} \ No newline at end of file diff --git a/app/lib/core/data/enums/letter.dart b/app/lib/core/data/enums/letter.dart new file mode 100644 index 0000000..9dcbeee --- /dev/null +++ b/app/lib/core/data/enums/letter.dart @@ -0,0 +1,6 @@ +enum Letter { + unknown, + notInWord, + wrongSpot, + correctSpot, +} diff --git a/app/lib/core/data/enums/message_types.dart b/app/lib/core/data/enums/message_types.dart new file mode 100644 index 0000000..1d12415 --- /dev/null +++ b/app/lib/core/data/enums/message_types.dart @@ -0,0 +1,3 @@ +enum MessageTypes{ + info,error,success +} \ No newline at end of file diff --git a/app/lib/core/presentation/home/cubit/home_cubit.dart b/app/lib/core/presentation/home/cubit/home_cubit.dart new file mode 100644 index 0000000..66d9de0 --- /dev/null +++ b/app/lib/core/presentation/home/cubit/home_cubit.dart @@ -0,0 +1,51 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:guessing_words/core/data/data_singleton.dart'; +import 'package:guessing_words/core/data/enums/keyboard_keys.dart'; +import 'package:guessing_words/core/data/enums/letter.dart'; +import 'package:guessing_words/core/data/enums/message_types.dart'; + +part 'home_state.dart'; + +class HomeCubit extends Cubit { + HomeCubit() : super(HomeInitial()); + DataSingleton data = DataSingleton(); + + void setLetter(KeyboardKeys key) { + if (data.setLetter(key)) { + emit(GridUpdateState()); + } + } + + void removeLetter() { + data.removeLetter(); + emit(GridUpdateState()); + } + + bool submitWord() { + final state = data.submitWord(); + if (state is GridUpdateState || + state is WinGameState || + state is LoseGameState) { + emit(state); + if (state is WinGameState) { + emit(GridUpdateState()); + } + return true; + }else if(state is SnackBarMessage){ + emit(state); + return false; + } + return false; + } + + void updateKey(KeyboardKeys key, Letter letterType) { + emit(KeyboardKeyUpdateState(key, letterType)); + } + + Future clearGameArea() async { + data.resetData(); + await data.createWord(); + emit(HomeInitial()); + } +} diff --git a/app/lib/core/presentation/home/cubit/home_state.dart b/app/lib/core/presentation/home/cubit/home_state.dart new file mode 100644 index 0000000..803728d --- /dev/null +++ b/app/lib/core/presentation/home/cubit/home_state.dart @@ -0,0 +1,49 @@ +part of 'home_cubit.dart'; + +abstract class HomeState extends Equatable { + const HomeState(); +} + +class HomeInitial extends HomeState { + @override + List get props => []; +} + +class GridUpdateState extends HomeState { + final id = DateTime.now().microsecondsSinceEpoch; + + @override + List get props => [id]; +} + +class KeyboardKeyUpdateState extends HomeState { + final id = DateTime.now().microsecondsSinceEpoch; + final KeyboardKeys key; + final Letter letterType; + + KeyboardKeyUpdateState(this.key, this.letterType); + + @override + List get props => [id,key,letterType]; +} + +class SnackBarMessage extends HomeState { + final id = DateTime.now().microsecondsSinceEpoch; + final MessageTypes type; + final String message; + + SnackBarMessage(this.type, this.message); + + @override + List get props => [id, type, message]; +} + +class LoseGameState extends HomeState { + @override + List get props => []; +} + +class WinGameState extends HomeState { + @override + List get props => []; +} diff --git a/app/lib/core/presentation/home/page/home_page.dart b/app/lib/core/presentation/home/page/home_page.dart new file mode 100644 index 0000000..b36a59c --- /dev/null +++ b/app/lib/core/presentation/home/page/home_page.dart @@ -0,0 +1,368 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_countdown_timer/countdown_timer_controller.dart'; +import 'package:flutter_countdown_timer/current_remaining_time.dart'; +import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:top_snackbar_flutter/custom_snack_bar.dart'; +import 'package:top_snackbar_flutter/top_snack_bar.dart'; +import 'package:twemoji/twemoji.dart'; +import 'package:guessing_words/core/const/color_constants.dart'; +import 'package:guessing_words/core/const/text_constants.dart'; +import 'package:guessing_words/core/data/data_singleton.dart'; +import 'package:guessing_words/core/data/enums/message_types.dart'; +import 'package:guessing_words/core/presentation/home/cubit/home_cubit.dart'; +import 'package:guessing_words/core/presentation/home/widget/home_content.dart'; + +class HomePage extends StatefulWidget { + const HomePage({Key? key}) : super(key: key); + + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State { + @override + void initState() { + super.initState(); + SchedulerBinding.instance.addPostFrameCallback((_) => _showTimerIfNeeded()); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + actions: [ + Padding( + padding: const EdgeInsets.only(right: 50), + child: GestureDetector( + onTap: () { + showDialog( + context: context, + builder: (BuildContext context) { + return BackdropFilter( + filter: ImageFilter.blur(sigmaX: 8.0, sigmaY: 8.0), + child: Dialog( + shape: const RoundedRectangleBorder( + borderRadius: + BorderRadius.all(Radius.circular(24.0)), + ), + child: _buildDialogBody(), + ), + ); + }); + }, + child: const Icon(Icons.help_outline)), + ), + ], + title: Text( + TextConstants.gameTitle, + style: GoogleFonts.mulish(fontSize: 32, fontWeight: FontWeight.w800), + ), + backgroundColor: Colors.white, + foregroundColor: Colors.black, + centerTitle: true, + shadowColor: Colors.transparent, + ), + body: _buildBody(context), + ); + } + + BlocProvider _buildBody(BuildContext context) { + return BlocProvider( + create: (BuildContext context) => HomeCubit(), + child: BlocConsumer( + listenWhen: (_, currState) => true, + listener: (context, state) { + final homeCubit = BlocProvider.of(context); + if (state is SnackBarMessage) { + SnackBarMessage message = state; + _showMessage(message, context); + } else if (state is WinGameState) { + _makeWin(homeCubit); + } else if (state is LoseGameState) { + _makeLose(homeCubit); + } + }, + buildWhen: (_, currState) => currState is HomeInitial, + builder: (context, state) { + return HomeContent( + key: UniqueKey(), + ); + }, + ), + ); + } + + void _showMessage(SnackBarMessage myMessage, BuildContext context) { + switch (myMessage.type) { + case MessageTypes.info: + showTopSnackBar( + context, + CustomSnackBar.info( + message: myMessage.message, + ), + ); + break; + case MessageTypes.success: + showTopSnackBar( + context, + CustomSnackBar.success( + message: myMessage.message, + ), + ); + break; + case MessageTypes.error: + showTopSnackBar( + context, + CustomSnackBar.error( + message: myMessage.message, + ), + ); + break; + } + } + + _buildDialogBody() { + return Container( + padding: const EdgeInsets.symmetric(vertical: 36, horizontal: 20), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(50)), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + alignment: Alignment.center, + width: double.infinity, + child: Text(TextConstants.howToPlayTitle, + style: GoogleFonts.mulish( + fontSize: 32, fontWeight: FontWeight.w700)), + ), + const SizedBox( + height: 20, + ), + Text(TextConstants.howToPlayText, + style: GoogleFonts.mulish( + fontSize: 15, fontWeight: FontWeight.w600)), + const SizedBox( + height: 20, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: ColorConstants.primaryGreyLight, + borderRadius: BorderRadius.circular(12)), + child: Center( + child: Text( + "A", + style: GoogleFonts.mulish( + fontSize: 26, fontWeight: FontWeight.w600), + ), + ), + ), + const SizedBox( + width: 16, + ), + Text(TextConstants.howToPlayRole1, + style: GoogleFonts.mulish( + fontSize: 15, fontWeight: FontWeight.w600)), + ], + ), + const SizedBox( + height: 20, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: ColorConstants.primaryOrange, + borderRadius: BorderRadius.circular(12)), + child: Center( + child: Text( + "A", + style: GoogleFonts.mulish( + fontSize: 26, fontWeight: FontWeight.w600), + ), + ), + ), + const SizedBox( + width: 16, + ), + Flexible( + child: Text(TextConstants.howToPlayRole2, + style: GoogleFonts.mulish( + fontSize: 15, fontWeight: FontWeight.w600))), + ], + ), + const SizedBox( + height: 20, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: ColorConstants.primaryGreen, + borderRadius: BorderRadius.circular(12)), + child: Center( + child: Text( + "A", + style: GoogleFonts.mulish( + fontSize: 26, fontWeight: FontWeight.w600), + ), + ), + ), + const SizedBox( + width: 20, + ), + Flexible( + child: Text(TextConstants.howToPlayRole3, + style: GoogleFonts.mulish( + fontSize: 15, fontWeight: FontWeight.w600))), + ], + ), + ], + ), + ); + } + + void _showTimerIfNeeded() async { + final s = await DataSingleton().createWord(); + SharedPreferences prefs = await SharedPreferences.getInstance(); + if (prefs.containsKey("last_game_word")) { + if (prefs.getString("last_game_word") == s) { + _showTimerDialog(prefs.getBool("last_game_result") ?? false); + } + } + } + + void _makeWin(homeCubit) async { + await _writeResults(true); + await homeCubit.clearGameArea(); + _showTimerIfNeeded(); + } + + void _makeLose(homeCubit) async { + await _writeResults(false); + await homeCubit.clearGameArea(); + _showTimerIfNeeded(); + } + + Future _writeResults(bool isWin) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + final lastWord = DataSingleton().secretWord; + if (lastWord.isNotEmpty) { + await prefs.setString('last_game_word', lastWord); + await prefs.setBool('last_game_result', isWin); + } + } + + void _showTimerDialog(bool isWin) { + final now = DateTime.now(); + final nextMidnight = + DateTime(now.year, now.month, now.day).add(const Duration(days: 1)); + final int endTime = DateTime.now().millisecondsSinceEpoch + + nextMidnight.difference(now).inMilliseconds; + final CountdownTimerController _countDownController = + CountdownTimerController(endTime: endTime, onEnd: _dismissTimerDialog); + showDialog( + barrierDismissible: false, + context: context, + barrierColor: Colors.transparent, + builder: (BuildContext ctx) { + return BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), + child: Dialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(24.0)), + ), + backgroundColor: isWin + ? ColorConstants.primaryGreenLight + : ColorConstants.primaryRedLight, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 40.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: double.infinity, + child: Center( + child: Text( + isWin ? TextConstants.youWin : TextConstants.youLose, + style: GoogleFonts.mulish( + fontSize: 32, fontWeight: FontWeight.w700), + )), + ), + const SizedBox( + height: 20, + ), + Twemoji( + emoji: isWin ? '🎉' : '😩', + height: 80, + width: 80, + ), + const SizedBox( + height: 30, + ), + SizedBox( + width: double.infinity, + child: Center( + child: Text( + TextConstants.nextWordle, + style: GoogleFonts.mulish( + fontSize: 25, fontWeight: FontWeight.w700), + )), + ), + const SizedBox( + height: 16, + ), + CountdownTimer( + controller: _countDownController, + widgetBuilder: (_, CurrentRemainingTime? time) { + if (time == null) { + return Container(); + } + final duration = Duration( + //hours: time.hours ?? 0, + minutes: time.min ?? 0, + seconds: time.sec ?? 0); + + return Text( + _durationToString(duration), + style: GoogleFonts.mulish( + fontSize: 20, fontWeight: FontWeight.w600), + ); + }, + ), + ], + ), + ), + ), + ); + }); + } + + void _dismissTimerDialog() async { + await DataSingleton().createWord(); + Navigator.of(context, rootNavigator: true).pop(); + } + + String _durationToString(Duration duration) { + String twoDigits(int n) => n.toString().padLeft(2, "0"); + String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); + String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); + return "$twoDigitMinutes:$twoDigitSeconds"; + } +} diff --git a/app/lib/core/presentation/home/widget/grid.dart b/app/lib/core/presentation/home/widget/grid.dart new file mode 100644 index 0000000..2b544bd --- /dev/null +++ b/app/lib/core/presentation/home/widget/grid.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:guessing_words/core/const/color_constants.dart'; +import 'package:guessing_words/core/data/data_singleton.dart'; +import 'package:guessing_words/core/presentation/home/cubit/home_cubit.dart'; + +class Grid extends StatelessWidget { + const Grid({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + buildWhen: (_, currentState) => currentState is GridUpdateState, + builder: (context, state) { + final data = DataSingleton(); + final letters = data.getLetters(); + return Container( + margin: const EdgeInsets.symmetric(horizontal: 30), + child: GridView.count( + mainAxisSpacing: 10, + crossAxisSpacing: 10, + scrollDirection: Axis.vertical, + shrinkWrap: true, + crossAxisCount: 5, + children: List.generate(30, (index) { + final letter = letters.length > index ? letters[index] : ""; + Color color = ColorConstants.primaryGreyLight; + if (letter.isNotEmpty && + data.currentWordIndex > 0 && + index < 5 * data.currentWordIndex) { + final indexInRow = index % 5; + if(data.gridData.join().contains(letter)){ + color=ColorConstants.primaryGreyMedium; + } + if (data.secretWord.contains(letter)) { + color = ColorConstants.primaryOrange; + } + if (data.secretWord[indexInRow] == letter) { + color = ColorConstants.primaryGreen; + } + } + return Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(12)), + color: color, + ), + child: Text( + letter.toUpperCase(), + style: GoogleFonts.mulish( + fontWeight: FontWeight.w600, fontSize: 30), + ), + ); + }), + ), + ); + }, + ); + } +} diff --git a/app/lib/core/presentation/home/widget/home_content.dart b/app/lib/core/presentation/home/widget/home_content.dart new file mode 100644 index 0000000..0b0cdcf --- /dev/null +++ b/app/lib/core/presentation/home/widget/home_content.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:guessing_words/core/presentation/home/widget/keyboard.dart'; + +import 'grid.dart'; + +class HomeContent extends StatelessWidget { + const HomeContent({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.only(top: 10), + width: double.infinity, + height: double.infinity, + color: Colors.white, + child: Column( + children: const [ + Grid(), + Spacer( + flex: 2, + ), + Keyboard(), + Spacer(), + ], + ), + ); + } +} diff --git a/app/lib/core/presentation/home/widget/keyboard.dart b/app/lib/core/presentation/home/widget/keyboard.dart new file mode 100644 index 0000000..f1ebcfd --- /dev/null +++ b/app/lib/core/presentation/home/widget/keyboard.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:guessing_words/core/data/enums/keyboard_keys.dart'; + +import 'keyboard_key.dart'; + +class Keyboard extends StatelessWidget { + const Keyboard({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: MediaQuery.of(context).size.width, + child: Column( + children: [ + Row( + children: const [ + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.q,)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.w)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.e)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.r)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.t)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.y)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.u)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.i)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.o)), + Flexible(flex:1,child: KeyboardKey(keyboardKey: KeyboardKeys.p)), + ], + ), + Row( + children: const [ + Spacer(flex: 5,), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.a,)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.s)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.d)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.f)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.g)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.h)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.j)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.k)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.l)), + Spacer(flex: 5,), + ], + ), + Row( + children: const [ + Flexible(flex:14,child: EnterKeyboardKey()), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.z)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.x)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.c)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.v)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.b)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.n)), + Flexible(flex:10,child: KeyboardKey(keyboardKey: KeyboardKeys.m)), + Flexible(flex:14,child: BackspaceKeyboardKey()), + ], + ), + ], + ), + ); + } +} diff --git a/app/lib/core/presentation/home/widget/keyboard_key.dart b/app/lib/core/presentation/home/widget/keyboard_key.dart new file mode 100644 index 0000000..9ded8e6 --- /dev/null +++ b/app/lib/core/presentation/home/widget/keyboard_key.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:guessing_words/core/data/data_singleton.dart'; +import 'package:guessing_words/core/data/enums/keyboard_keys.dart'; +import 'package:guessing_words/core/data/enums/letter.dart'; +import 'package:guessing_words/core/presentation/home/cubit/home_cubit.dart'; + +class KeyboardKey extends StatelessWidget { + const KeyboardKey( + {Key? key, this.color = Colors.black26, required this.keyboardKey}) + : super(key: key); + + final Color color; + final KeyboardKeys keyboardKey; + + @override + Widget build(BuildContext context) { + final homeCubit = BlocProvider.of(context); + return BlocBuilder( + buildWhen: (_, currentState) { + if (currentState is KeyboardKeyUpdateState) { + KeyboardKeyUpdateState state = currentState; + if (state.key.name == keyboardKey.name) { + return true; + } + } + return false; + }, + builder: (context, currentState) { + final data = DataSingleton(); + return Padding( + padding: const EdgeInsets.all(4.0), + child: InkWell( + onTap: () { + homeCubit.setLetter(keyboardKey); + }, + child: AspectRatio( + aspectRatio: 2 / 3, + child: Container( + decoration: BoxDecoration( + color: data.getKeyColor(keyboardKey), + borderRadius: BorderRadius.circular(4.6)), + child: Center( + child: Text( + keyboardKey.name.toUpperCase(), + style: const TextStyle(fontWeight: FontWeight.w500), + ), + ), + ), + ), + ), + ); + }, + ); + } +} + +class EnterKeyboardKey extends StatelessWidget { + const EnterKeyboardKey({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final homeCubit = BlocProvider.of(context); + final data = DataSingleton(); + return Padding( + padding: const EdgeInsets.all(4.0), + child: AspectRatio( + aspectRatio: 1 / 1, + child: InkWell( + onTap: () { + if (homeCubit.submitWord()) { + data.gridData[data.currentWordIndex - 1] + .split("") + .asMap() + .map((index, e) { + final key = + KeyboardKeys.values.firstWhere((KeyboardKeys element) { + return element.name == e; + }); + if (data.secretWord[index] == e) { + homeCubit.updateKey(key, Letter.correctSpot); + return MapEntry(index, e); + } + if (data.secretWord.contains(e)) { + homeCubit.updateKey(key, Letter.wrongSpot); + return MapEntry(index, e); + } + homeCubit.updateKey(key, Letter.notInWord); + return MapEntry(index, e); + }); + } + }, + child: Container( + decoration: BoxDecoration( + color: Colors.black26, + borderRadius: BorderRadius.circular(4.6)), + child: Center( + child: Text( + KeyboardKeys.enter.name.toUpperCase(), + style: const TextStyle(fontWeight: FontWeight.w500), + ), + ), + ), + ), + ), + ); + } +} + +class BackspaceKeyboardKey extends StatelessWidget { + const BackspaceKeyboardKey({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final homeCubit = BlocProvider.of(context); + return Padding( + padding: const EdgeInsets.all(4.0), + child: AspectRatio( + aspectRatio: 1 / 1, + child: InkWell( + onTap: () { + homeCubit.removeLetter(); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.black26, + borderRadius: BorderRadius.circular(4.6)), + child: const Center( + child: Icon(Icons.backspace_outlined), + ), + ), + ), + ), + ); + } +} diff --git a/app/lib/main.dart b/app/lib/main.dart index 202509b..7b9e49b 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -1,115 +1,19 @@ import 'package:flutter/material.dart'; +import 'package:fullscreen/fullscreen.dart'; +import 'core/presentation/home/page/home_page.dart'; void main() { - runApp(const MyApp()); + runApp(const GuessingWords()); } -class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); - - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({Key? key, required this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } +class GuessingWords extends StatelessWidget { + const GuessingWords({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. + FullScreen.enterFullScreen(FullScreenMode.EMERSIVE_STICKY); + return const MaterialApp( + home: HomePage(), ); } } diff --git a/app/pubspec.lock b/app/pubspec.lock index d5366a4..0453e39 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.2" + bloc: + dependency: transitive + description: + name: bloc + url: "https://pub.dartlang.org" + source: hosted + version: "8.0.3" boolean_selector: dependency: transitive description: @@ -43,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" cupertino_icons: dependency: "direct main" description: @@ -50,6 +64,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + desktop_window: + dependency: "direct main" + description: + name: desktop_window + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.0" + equatable: + dependency: "direct main" + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" fake_async: dependency: transitive description: @@ -57,11 +85,39 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + url: "https://pub.dartlang.org" + source: hosted + version: "8.0.1" + flutter_countdown_timer: + dependency: "direct main" + description: + name: flutter_countdown_timer + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" flutter_lints: dependency: "direct dev" description: @@ -69,11 +125,65 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + flutter_svg: + dependency: transitive + description: + name: flutter_svg + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + fullscreen: + dependency: "direct main" + description: + name: fullscreen + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.4" lints: dependency: transitive description: @@ -94,7 +204,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" meta: dependency: transitive description: @@ -102,13 +212,174 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.7.0" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" + path_drawing: + dependency: transitive + description: + name: path_drawing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.12" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + provider: + dependency: transitive + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.2" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.13" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + shared_preferences_ios: + dependency: transitive + description: + name: shared_preferences_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_web: + dependency: "direct main" + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" sky_engine: dependency: transitive description: flutter @@ -120,7 +391,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" stack_trace: dependency: transitive description: @@ -155,7 +426,21 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" + top_snackbar_flutter: + dependency: "direct main" + description: + name: top_snackbar_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + twemoji: + dependency: "direct main" + description: + name: twemoji + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.2" typed_data: dependency: transitive description: @@ -169,6 +454,35 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.5.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+1" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "5.3.1" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" sdks: - dart: ">=2.16.0-134.5.beta <3.0.0" + dart: ">=2.16.0-100.0.dev <3.0.0" + flutter: ">=2.10.0-0" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 3edbc3e..4f42514 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -1,89 +1,34 @@ name: guessing_words description: A new Flutter project. -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html version: 1.0.0+1 environment: - sdk: ">=2.16.0-134.5.beta <3.0.0" + sdk: ">=2.15.1 <3.0.0" -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. + flutter_bloc: ^8.0.1 + top_snackbar_flutter: ^1.0.2 + flutter_countdown_timer: ^4.1.0 + shared_preferences: ^2.0.12 + equatable: ^2.0.3 + twemoji: ^0.4.2 cupertino_icons: ^1.0.2 + google_fonts: ^2.2.0 + shared_preferences_web: ^2.0.3 + desktop_window: ^0.4.0 + fullscreen: ^1.0.3 dev_dependencies: flutter_test: sdk: flutter - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. flutter_lints: ^1.0.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages + assets: + - assets/words.txt diff --git a/app/test/widget_test.dart b/app/test/widget_test.dart index 49fc37b..6fad2ed 100644 --- a/app/test/widget_test.dart +++ b/app/test/widget_test.dart @@ -13,7 +13,7 @@ import 'package:guessing_words/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); + await tester.pumpWidget(const GuessingWords()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); diff --git a/app/windows/flutter/generated_plugin_registrant.cc b/app/windows/flutter/generated_plugin_registrant.cc index 8b6d468..1923f29 100644 --- a/app/windows/flutter/generated_plugin_registrant.cc +++ b/app/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + DesktopWindowPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("DesktopWindowPlugin")); } diff --git a/app/windows/flutter/generated_plugins.cmake b/app/windows/flutter/generated_plugins.cmake index 4d10c25..5601eb6 100644 --- a/app/windows/flutter/generated_plugins.cmake +++ b/app/windows/flutter/generated_plugins.cmake @@ -3,6 +3,10 @@ # list(APPEND FLUTTER_PLUGIN_LIST + desktop_window +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST ) set(PLUGIN_BUNDLED_LIBRARIES) @@ -13,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST}) list(APPEND PLUGIN_BUNDLED_LIBRARIES $) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin)