Four Letter Word generator based on an associative word dictionary.
Dependencies: _24LCXXX
Dependents: vfd_modular_clock_mbed
Four Letter Word generator based on an associative word dictionary.
Needs an EEPROM to function (can be programmed onto a 24LC512 I2C EEPROM, or available as a pre-programmed add-on board)
Comes with a censored mode that removes expletives as well as a fully uncensored mode.
For details see:
flw.cpp
- Committer:
- Backstrom
- Date:
- 2017-01-13
- Revision:
- 9:93f52963c4ff
- Parent:
- 6:f3455eff2ae4
File content as of revision 9:93f52963c4ff:
/* * Four Letter Word Generator * (C) 2015 Akafugu Corporation * * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * */ /* * To use this Four Letter Word generator you will need the following: * * - A 512kbit/64kb I2C EEPROM * - A database file, generated from this Processing application: * https://github.com/perjg/fourletterword * - A method for uploading the data file to the EEPROM * (Either an Arduino Mega, or a normal Arduino with a micro SD card) */ #include <string.h> #include "flw.h" #include "flw_blacklist.h" #define EEPROM_ADDR 0b1010000 void FourLetterWordBase::rot13(char* w) { while (*w != '\0') { if (*w >= 'A' && *w <= 'M') { *w += 13; } else if (*w >= 'N' && *w <= 'Z') { *w -= 13; } w++; } } bool FourLetterWordBase::binary_search(const char *key, int imin, int imax) { int pos; int cond = 0; char buf[5]; while (imin <= imax) { pos = (imin+imax) / 2; strcpy(buf, flw_blacklist[pos]); rot13(buf); cond = strcmp(key, buf); if (cond == 0) return true; else if (cond>0) imin = pos+1; else imax = pos-1; } return false; } void FourLetterWordBase::begin(uint32_t seed, bool censored) { m_lfsr = seed + 1; m_censored = censored; } uint32_t FourLetterWordBase::randomize() { // http://en.wikipedia.org/wiki/Linear_feedback_shift_register // Galois LFSR: taps: 32 31 29 1; characteristic polynomial: x^32 + x^31 + x^29 + x + 1 */ m_lfsr = (m_lfsr >> 1) ^ (-(m_lfsr & 1u) & 0xD0000001u); return m_lfsr; } bool FourLetterWordBase::hasEeprom() { uint8_t b1 = read_byte(0); uint8_t b2 = read_byte(1); if (b1 == 65 && b2 == 66) return true; return false; } char* FourLetterWordBase::get_word_censored() { char* w = get_word_uncensored(); // assume a maximum of 5 censored words chosen in a row for (uint8_t i = 0; i < 5; i++) { if (binary_search(w, 0, BLACKLIST_SIZE)) { // censored w = get_word_uncensored(); } else return w; } return w; } char* FourLetterWordBase::get_word_uncensored() { unsigned char low = 0xFF, high = 0xFF; unsigned char count = 0; int next = 0; read_buffer(m_offset, (uint8_t*)m_current_word, 5); count = m_current_word[4]; m_current_word[4] = '\0'; next = randomize() % count; m_offset += 5 + next * 2; high = read_byte(m_offset++); low = read_byte(m_offset++); m_offset = (high << 8) | low; return m_current_word; } char* FourLetterWordBase::getWord(bool adjustCase) { char* ret; if (m_censored) ret = get_word_censored(); ret = get_word_uncensored(); if (adjustCase) { // lowercase letters ret[1] += 32; ret[2] += 32; ret[3] += 32; } return ret; } ///////////////////////////////////////////////////// // EEPROM uint8_t FourLetterWord::read_byte(unsigned int addr) { uint8_t rdata = 0xFF; _24lc.nbyte_read(addr, &rdata, 1); return rdata; } void FourLetterWord::read_buffer(unsigned int addr, uint8_t *buffer, int length) { _24lc.nbyte_read(addr, buffer, length); } ///////////////////////////////////////////////////// // Data stored in local array uint8_t FourLetterWordLocal::read_byte(unsigned int addr) { return data[addr]; } void FourLetterWordLocal::read_buffer(unsigned int addr, uint8_t *buffer, int length) { unsigned char* ptr = (unsigned char*)data; ptr += addr; memcpy(buffer, ptr, length); }