Tìm một từ trong trò chơi ô chữ Python

Như tôi đã đề cập trong một blog trước, một trong những chương trình đầu tiên tôi viết bằng Python là một trình kiểm tra từ đơn giản. Bạn nhập một từ và nó sẽ kiểm tra xem từ đó có tồn tại trong từ điển không. Khi tôi có thể lập trình, tôi có thể mở rộng chương trình thành một trò giải ô chữ

Một trong những điều tuyệt vời về lập trình là bạn có thể sử dụng lại mã bạn đã viết. Một số mã tôi đã viết trong chương trình kiểm tra từ của mình có thể được sử dụng lại tại đây. Nếu bạn chưa làm như vậy, bạn có thể nên đọc qua bài đăng trên blog của tôi về việc lập trình trình kiểm tra từ, trước khi tiếp tục với bài đăng này

Bài đăng trên blog của Trình kiểm tra từ

Một lần nữa, chương trình này khá nhỏ, nhưng tôi nghĩ nó thể hiện sức mạnh của Python, rằng bạn có thể đạt được rất nhiều điều trong một vài dòng mã



Ý tưởng đằng sau Trình giải ô chữ là bạn nhập một từ bị thiếu một số chữ cái và chương trình sẽ tìm ra tất cả các từ có thể phù hợp với các chữ cái và dấu cách đã biết

Vì vậy, chẳng hạn nếu bạn có một từ chưa hoàn chỉnh trong trò chơi ô chữ và bạn biết chữ cái đầu tiên là 'f', bạn không biết chữ cái thứ hai hoặc thứ ba, nhưng biết chữ cái thứ tư là 's' và chữ cái thứ năm là 't'. tôi. e. bạn đang cố gắng tìm tất cả các từ phù hợp với 'f??st'

giải pháp sẽ là

ăn bám
tiệc
Con chó con
đầu tiên
chống đỡ
sương giá

Sẽ có 6 từ phù hợp

Blog này là một hướng dẫn dạy bạn cách tạo một chương trình để giải quyết vấn đề này cho bạn

Trước khi lập trình, bạn sẽ cần truy cập vào một từ điển mà chương trình của bạn có thể truy cập. Nếu bạn chưa làm, vui lòng tải xuống tệp DictionaryE. txt từ liên kết dưới đây. Đây là một tệp văn bản chứa rất nhiều từ

Nhấn vào đây để tải về từ điển. txt

Trong suốt blog này, nơi có thể có sự nhầm lẫn, tôi sẽ chỉ cho bạn cách nhập và sau đó hiển thị cho bạn một đoạn mã hiển thị dòng bạn cần nhập và dòng trước đó. Điều này sẽ tránh mọi nhầm lẫn về nơi bạn nên nhập mã và sẽ hiển thị cho bạn mức độ thụt đầu dòng cần thiết cho mỗi dòng

Ok chúng ta hãy bắt đầu

Khi viết một chương trình, trước tiên tôi luôn lập kế hoạch đại khái cho chương trình và chia nó thành các phần nhỏ hơn. Nó luôn có vẻ ít khó khăn hơn nhiều khi bạn nghĩ về từng phần riêng lẻ, thay vì toàn bộ chương trình. Vì vậy, đối với một người giải ô chữ, chúng ta cần phải làm gì?


  • Giai đoạn 1. Bằng cách nào đó, chúng ta cần nhập từ chưa hoàn chỉnh của mình để cho chương trình biết chúng ta đang cố gắng giải quyết vấn đề gì
  • giai đoạn 2. Chúng tôi cũng cần có thể truy cập danh sách các từ thực trong từ điển
  • Giai đoạn 3. Sau đó, chúng tôi sẽ phải so sánh từ chưa hoàn chỉnh của mình với các từ trong từ điển và xác định xem chúng có phải là từ phù hợp tiềm năng không
  • giai đoạn 4. Cuối cùng, chúng ta sẽ cần in bất kỳ từ nào phù hợp với tiêu chí


Bây giờ chúng tôi đã lên kế hoạch cho chương trình của mình, bây giờ chúng tôi có thể bắt đầu lập trình nó

Giai đoạn 1


Hãy nhớ trước đó tôi đã nói rằng chúng tôi có thể sử dụng lại mã mà chúng tôi đã viết? . Vì vậy, hãy sử dụng cùng một mã ở đây

Trong một cửa sổ Python mới gõ như sau

testWord = raw_input ('Please input a word to solve.\nUse Spaces to signify unkown letters: ').lower()

Điều này lưu trữ từ của chúng ta thành một biến gọi là testWord

\n yêu cầu chương trình in văn bản tiếp theo trên một dòng mới

Sự khác biệt duy nhất giữa dòng này và dòng trong chương trình kiểm tra từ là thực tế là tôi đã thay đổi văn bản giải thích đầu vào nào được yêu cầu

giai đoạn 2


Chúng ta cần có khả năng nhìn vào một danh sách các từ thực. Điều này hoàn toàn giống như trong chương trình kiểm tra từ

Do đó, bạn có thể sao chép hàm getDictionary() vào đầu chương trình của mình

def getDictionary():
    dictionaryOpen = open('dictionaryE.txt','r')
    dictionary = dictionaryOpen.read().split()
    dictionaryOpen.close()
    return dictionary


Ok vậy là xong Giai đoạn 2. Chúng tôi đã thực hiện một nửa chương trình của mình và không phải nhập bất kỳ mã mới nào. Bạn nên sử dụng lại mã bất cứ khi nào có thể, vì nó giúp bạn tiết kiệm rất nhiều thời gian

Giai đoạn 3


Trong giai đoạn này, chúng ta cần so sánh từ chưa hoàn chỉnh của mình với tất cả các từ trong từ điển

Điều này phức tạp hơn một chút so với chức năng testWord trong chương trình kiểm tra từ, vì vậy trước tiên hãy nghĩ về cách chúng ta sẽ tiếp cận điều này

Bây giờ chúng tôi có một danh sách các từ thực trong từ điển và một từ không đầy đủ. Chúng tôi muốn tìm tất cả các giải pháp tiềm năng

Chúng ta có thể tập hợp một số quy tắc, nếu tuân theo, sẽ kiểm tra một từ trong từ điển và tìm từ phù hợp tiềm năng với từ chưa hoàn chỉnh của chúng ta

Quy tắc 1
Chúng tôi biết rằng để một từ trong từ điển có thể khớp với từ chưa hoàn thiện của chúng tôi, chúng cần phải có cùng độ dài. Vì vậy, chúng tôi sẽ chỉ xem xét các từ có cùng độ dài và loại trừ tất cả những từ có độ dài khác nhau

Quy tắc 2
Vì các khoảng trống có hiệu lực là các thẻ đại diện và có thể là bất kỳ chữ cái nào chúng tôi muốn bỏ qua bất kỳ khoảng trống nào trong từ chưa hoàn chỉnh của chúng tôi

Quy tắc 3
Đối với bất kỳ chữ cái nào trong từ chưa hoàn chỉnh của chúng tôi, chúng tôi muốn xem liệu nó có khớp với chữ cái tương ứng của mỗi từ trong từ điển không. tôi. e. Chúng tôi muốn đảm bảo rằng chữ cái đầu tiên trong từ của chúng tôi khớp với chữ cái đầu tiên của từ trong từ điển. Chúng tôi muốn làm tương tự cho chữ cái thứ hai và chữ cái thứ ba, v.v. Chúng tôi muốn có thể biết liệu tất cả các chữ cái không trống trong từ không hoàn chỉnh của chúng tôi có khớp với các chữ cái tương ứng của từ trong từ điển hay không

Vì vậy, đây là ba quy tắc của chúng tôi tóm tắt

  • Kiểm tra các từ có cùng độ dài
  • Bỏ qua mọi khoảng trống
  • So sánh chữ cái đầu tiên của từ chưa hoàn chỉnh với chữ cái đầu tiên của từ trong từ điển. Sau đó, thứ hai vv. Kiểm tra tất cả chúng phù hợp


Ba quy tắc này đã đủ để giải câu đố chưa?

Hãy xem xét một ví dụ và chúng tôi sẽ sử dụng ví dụ về từ không hoàn chỉnh của chúng tôi là

'f  st'


với hai khoảng trống sau f

Hãy so sánh từ này với từ quả táo bằng cách sử dụng các quy tắc của chúng tôi ở trên

Cả hai đều có cùng độ dài, vì vậy quy tắc 1 được thỏa mãn

Chúng tôi có thể bỏ qua từng chữ cái theo cách thủ công và so sánh chữ cái 1 từ 'f  st' với 'apple'
điều này sẽ so sánh
f -> một
bỏ qua hai chữ cái tiếp theo vì chúng là khoảng trống (Quy tắc 2)
s -> l
t -> e

Để đáp ứng Quy tắc 3, tất cả các chữ cái không trống sẽ phải khớp với các chữ cái tương ứng trong từ trong từ điển. Trong trường hợp này, 0 trong số ba ô trống không khớp. Đây không phải là một trận đấu tiềm năng

Sẽ thế nào nếu chúng ta so sánh 'f  st' với 'first'

f -> f
bỏ qua hai chữ cái tiếp theo vì chúng là khoảng trống. (Quy tắc 2)
s -> s
t -> t

Chúng tôi đếm những cái phù hợp, trong trường hợp này là 3 và so sánh số này với số lượng không có chữ cái trống nào là 3. Vì vậy có thể nói đây là một trận đấu tiềm năng

Tôi khá tự tin rằng ba quy tắc này sẽ đáp ứng những gì chúng ta cần, vì vậy tôi sẽ bắt đầu lập trình một hàm để thực hiện phép so sánh này

Hãy bắt đầu với việc tạo chức năng của chúng tôi. Bên dưới hàm getDictionary gõ như sau

def checkWord (testWord, từ điển)

def checkWord (testWord,dictionary):

Chúng tôi sẽ gọi hàm checkWord của mình và sẽ chuyển cả biến testWord và từ điển vào hàm này để chúng tôi có thể sử dụng cả hai biến này để so sánh

Chúng tôi biết từ các quy tắc của mình rằng để trở thành một đối sánh tiềm năng, tất cả các chữ cái không trống phải khớp với từ trong từ điển. Do đó, chúng tôi sẽ cần xác định số lượng chữ cái không trống trong từ kiểm tra của chúng tôi. Điều này có thể được thực hiện trước khi chúng tôi xem xét bất kỳ từ nào trong từ điển, vì vậy hãy xem xét điều này ngay bây giờ

Trước khi nhập thêm bất kỳ thứ gì vào chương trình của chúng ta, chúng ta sẽ xem xét hai lệnh python hữu ích mà chúng ta sẽ sử dụng để tìm ra số lượng không có khoảng trống nào

Đầu tiên là len()

len(testWord)

cho chúng tôi biết testWord dài bao nhiêu

Vì vậy, đó là tổng chiều dài của từ bao gồm khoảng trống

Chúng ta có thể sử dụng lệnh thứ hai trên testWord để đếm số lượng khoảng trống

Đây là

kiểm tra từ. đếm(' ')

Vì vậy, nếu có hai khoảng trống, điều này sẽ tạo ra số 2

Vì vậy, nếu chúng ta biết có bao nhiêu chữ cái trong từ và bao nhiêu là khoảng trống, chúng ta có thể suy ra số không phải là khoảng trống

Do đó, nếu chúng ta tạo một biến có tên là nonBlanks, chúng ta sẽ dễ dàng tìm ra số ký tự nonBlank trong từ của mình. Do đó, hãy nhập phương trình này vào chức năng của bạn

nonBlanks = len(testWord)-testWord. đếm(' ')


def checkWord (testWord,dictionary):
    
    nonBlanks = len(testWord)-testWord.count(' ')


Đối với phần còn lại của chức năng, chúng ta cần kiểm tra từng từ trong từ điển và so sánh chúng với từ chưa hoàn chỉnh của chúng ta

Để lặp lại từng từ trong từ điển của chúng tôi tại một thời điểm, chúng tôi chỉ cần nói

cho từ trong từ điển

    nonBlanks = len(testWord)-testWord.count(' ')
    for word in dictionary:

Mọi thứ bên trong vòng lặp for này sẽ được thực hiện trên từng từ riêng lẻ

Khi chúng tôi kiểm tra từng từ, có một số điều chúng tôi nên theo dõi


  • Chúng ta cần biết chữ cái nào trong cả từ của chúng ta và từ trong từ điển mà chúng ta đang so sánh
  • Chúng tôi muốn có thể giữ số lượng của bất kỳ chữ cái không trống nào phù hợp


Vì vậy, hãy tạo hai biến mà chúng ta có thể tăng khi chúng ta đếm

incChữ = 0
incMatch = 0

    for word in dictionary:
        incLetter = 0
        incMatch = 0

incLetter sẽ tăng lên khi chúng tôi kiểm tra từng chữ cái. Điều này sẽ theo dõi những gì thư chúng tôi đang xem
incMatch sẽ tăng lên khi chúng tôi khớp một chữ cái

Với những thứ này nằm trong vòng lặp for, chúng sẽ đặt lại về 0 mỗi khi một từ mới được kiểm tra. Chỉ là những gì chúng ta muốn

Bước tiếp theo là bắt đầu thu hẹp các lựa chọn tiềm năng. Cách tốt nhất để làm điều này là loại bỏ bất kỳ từ nào không cùng độ dài với từ tiềm năng của chúng ta, đó là Quy tắc 1

Chúng ta có thể sử dụng hàm len() mà chúng ta đã sử dụng trước đó để trợ giúp việc này

nếu len(word) == len(testWord)

        incMatch = 0
        if len (word) == len (testWord):

Vì vậy, chúng tôi sẽ chỉ tiến xa hơn nếu các từ phù hợp về độ dài

bây giờ hãy bắt đầu một vòng lặp for khác để cho phép chúng tôi kiểm tra từng chữ cái riêng lẻ

cho chữ cái trong testWord

        if len (word) == len (testWord):
            for letter in testWord:

Điều này sẽ đi qua testWord của chúng tôi một chữ cái tại một thời điểm

Có ba lựa chọn bây giờ


  • Nếu ký tự trống, chúng tôi muốn bỏ qua ký tự đó, nhưng chúng tôi muốn đảm bảo rằng chúng tôi chuyển sang ký tự tiếp theo trong từ bao gồm Quy tắc 2
  • Nếu nó không phải là một khoảng trống, chúng tôi muốn kiểm tra xem chữ cái này có khớp với chữ cái tương ứng của từ trong từ điển không. Tăng incMatch nếu các từ khớp. Sau đó, chúng tôi cũng muốn chuyển sang chữ cái tiếp theo trong từ. Điều này giúp với Quy tắc 3
  • Nếu nó không khớp, chúng tôi chỉ muốn chuyển sang chữ cái tiếp theo. Một lần nữa, điều này giúp với Quy tắc 3


Phần đầu tiên là kiểm tra xem nó có trống không và nếu có thì chuyển sang chữ cái tiếp theo

nếu thư == ''
incChữ cái += 1

________số 8_______
Vì vậy, chúng tôi nói nếu chữ cái bằng một khoảng trống, hãy tăng incLetter một

incLetter += 1 là cách nói ngắn gọn của incLetter = incLetter + 1
hoặc tăng incLetter lên 1

Tùy chọn thứ hai nếu chữ cái không trống nên đọc

thư elif == từ [incLetter]
incChữ cái += 1
incMatch += 1

                    incLetter += 1
                elif letter == word[incLetter]:
                    incLetter +=1
                    incMatch +=1

Word[incLetter] đang nói gì? . Nhấp vào Window và sau đó nhấp vào Python Shell để tải cửa sổ trình bao

Tạo một biến gọi là từ và lưu trữ 'quả táo' trong đó

từ = 'quả táo'



Sau đó, chúng ta có thể tìm ra từng chữ cái riêng lẻ trong từ là gì bằng cách nhập nội dung sau

từ [0] trả về 'a'
từ [1] trả về 'p'
từ [2] trả về 'p'
từ [3] trả về 'l'
từ [4] trả về 'e'




như incLetter = 0 chúng tôi biết chúng tôi đang nhìn vào chữ cái đầu tiên. Nếu incLetter là 1, chúng ta sẽ xem xét chữ cái thứ hai, v.v. Vì vậy, đó là một cách để di chuyển qua từ và theo dõi xem chúng ta đang ở đâu

Nếu các chữ cái tương ứng của cả hai từ khớp nhau, chúng tôi sẽ tăng incLetter để chuyển sang chữ cái tiếp theo và chúng tôi cũng sẽ tăng incMatch để nói các chữ cái khớp nhau

Tùy chọn thứ ba là nếu các từ không trống và không khớp. Chúng tôi không muốn làm bất cứ điều gì ở đây ngoài việc chuyển sang chữ cái tiếp theo

khác
incChữ cái += 1


def getDictionary():
    dictionaryOpen = open('dictionaryE.txt','r')
    dictionary = dictionaryOpen.read().split()
    dictionaryOpen.close()
    return dictionary
0
Trông nó thế nào? . Mỗi tùy chọn chúng tôi tăng incLetter và chỉ làm điều gì đó khác biệt, tăng incMatch, nếu các chữ cái khớp

Hãy viết lại phần đó từ 'cho chữ cái trong testWord. ' để làm cho nó ngắn hơn

cho chữ cái trong testWord
nếu thư == từ [incLetter]
incMatch +=1
incChữ cái += 1

def getDictionary():
    dictionaryOpen = open('dictionaryE.txt','r')
    dictionary = dictionaryOpen.read().split()
    dictionaryOpen.close()
    return dictionary
1
Vì vậy, điều này nói rằng nếu các chữ cái khớp nhau, hãy tăng incMatch nhưng không có vấn đề gì chúng ta cần tăng incLetter để chúng ta bắt đầu xem xét chữ cái tiếp theo

Tôi nghĩ điều đó đã làm gọn gàng chương trình của chúng ta một chút. Thông thường, khi bạn nhìn thấy mã trên trang, rõ ràng là mọi thứ có thể được cải thiện. nó không phải là một điều xấu. Một điều tôi muốn nói là đảm bảo rằng bất cứ điều gì bạn làm, bạn sẽ hiểu nó khi bạn nhìn vào nó sau vài tuần, vài tháng hoặc thậm chí vài năm. Nếu bạn sử dụng một vài dòng bổ sung, nhưng nó làm cho mã của bạn dễ đọc hơn, thì hãy để mã dài hơn

Bây giờ chúng tôi đã xem qua từng chữ cái trong từ và so sánh chúng, chúng tôi cần báo cáo lại nếu từ đó khớp hay không. Điều này đưa chúng ta vào giai đoạn cuối cùng

giai đoạn 4


Chúng tôi đã nói ngay từ đầu rằng chúng tôi sẽ in bất kỳ từ nào phù hợp lên màn hình, vì vậy hãy cứ làm điều đó

Kế hoạch của chúng tôi là đối với các từ có cùng độ dài, nếu số lượng chữ cái phù hợp bằng số lượng chữ cái không trống thì chúng tôi có một giải pháp tiềm năng. Như chúng ta đã xác định nếu các từ có cùng độ dài, chúng ta có thể nói

nếu incMatch == nonBlanks
in (từ)

def getDictionary():
    dictionaryOpen = open('dictionaryE.txt','r')
    dictionary = dictionaryOpen.read().split()
    dictionaryOpen.close()
    return dictionary
2Sau đó chúng ta sẽ chuyển sang từ tiếp theo trong từ điển. Điều này đã được chăm sóc cho chúng tôi trong vòng lặp for

Khi vòng lặp đã duyệt qua mọi từ trong từ điển, chúng ta sẽ thoát khỏi hàm bằng một lệnh trả về đơn giản

trở lại

def getDictionary():
    dictionaryOpen = open('dictionaryE.txt','r')
    dictionary = dictionaryOpen.read().split()
    dictionaryOpen.close()
    return dictionary
3
Cho đến nay chúng tôi đã làm như sau


  • Chúng tôi đã yêu cầu người dùng nhập một từ chưa hoàn chỉnh mà họ muốn giải
  • Chúng tôi có một chức năng để tạo một từ điển
  • Chúng tôi có một chức năng so sánh một từ với từng từ trong từ điển và báo cáo lại bất kỳ giải pháp tiềm năng nào


Tất cả những gì chúng ta cần bây giờ là buộc mọi thứ lại với nhau

Bên dưới đầu vào của người dùng, hãy lấy từ điển và gán nó cho một biến mà chúng ta có thể chuyển vào hàm của mình

từ điển = getDictionary()

Cuối cùng, chúng ta có thể chạy testWord và từ điển thông qua chức năng checkWord

checkWord (testWord, từ điển)

def getDictionary():
    dictionaryOpen = open('dictionaryE.txt','r')
    dictionary = dictionaryOpen.read().split()
    dictionaryOpen.close()
    return dictionary
4
Nhấn F5 bây giờ sẽ lưu và chạy chương trình của bạn


Nhập 'f  st' khi được hỏi sẽ dẫn đến kết quả như sau


Nếu bạn muốn tải xuống mã nguồn, bạn có thể từ liên kết sau

Mã nguồn giải ô chữ

Đây rồi, điều đó sẽ giúp bạn giải bất kỳ ô chữ nào. Hôm nay chúng ta đã thấy một số khái niệm mới và ban đầu có vẻ hơi khó khăn. Điều quan trọng là chia nhỏ mọi thứ thành yếu tố cơ bản nhất của nó

Nếu bạn đang gặp khó khăn để hiểu, chỉ cần đọc từng dòng mã một và xem liệu bạn có thể tìm ra nó đang làm gì không