void view() { int wy; while (!feof(file1)||feof(file1)) { for (i=0; i<24; i++) { fgets(line,k,file1); if (feof(file1)) ende(); len=strlen(line); if (z==1) { printf ("%d %s",zeile,line); if (len>=77) { wy=wherey(); gotoxy(1,wy-1); } } else printf("%s",line); zeile++; } bild=1; printf("Taste..."); c=getch(); clrscr(); } ende(); }
void ok(int sd) { if (senden(sd, "OK\n") < 0) { perror("Ok senden"); ende(-1); } }
void main() { oeffnen(); eingabe(); ausgabe(); ende(); }
/*------------------------------------------------------------------------------------*/ void usage(char *progname) /* Bedienungsanleitung */ { printf("Aufruf: %s [Optionen] Hostname\n", progname); printf("Optionen:\n"); printf("\t-p #\tPortnummer setzen (default: 12345)\n"); ende(0); }
/*------------------------------------------------------------------------------------*/ int ok(int sd) { if(senden(sd, "OK\n") < 0) { perror("Ok senden"); ende(-1); } return 0; }
/*------------------------------------------------------------------------------------*/ void abfangen(int sig) { if (2-excode !=0) printf("\nStrg-C noch %dx druecken zum Beenden.\n", 2 - excode); excode++; if(excode == 3) { ende(0); } else { fflush(stdout); } return; }
int main(void) { printf("Spielplan Eingabe V 1.0\n\n"); open_file(); spielzeit(); teamnamen_eingeben(0); teamnamen_eingeben(1); team_liste(); spielplan_eingeben(); fprintf(f, "---ergebnisse---\n"); close(f); ende(); return 0; }
/* Konstruktor */ Basis::Basis() : ProgrammFenster() { this->setGeometry(195, 200, 140, 72); taste = new QPushButton("Ende",this); taste->setGeometry(20, 10, 100, 50); taste->show(); connect(taste, SIGNAL(clicked()), SLOT(ende())); r = new Rechts(0); r->show(); connect(r, SIGNAL(sichtbarmachen(int)), SLOT(einschalten(int))); l = new Links(0); l->show(); connect(l, SIGNAL(sichtbarmachen(int)), SLOT(einschalten(int))); }
/*------------------------------------------------------------------------------------*/ void str_senden(int sd, char topic[MAXLEN], char data[MAXLEN], int rc) { char buffer[MAXLEN]; *(data+rc-1) = (char) 0; /* String erstellen */ strncpy(buffer, topic,MAXLEN); strncat(buffer, data, MAXLEN - strlen(data) - 2); strncat(buffer, "\n", MAXLEN - strlen(buffer) - 1 ); /* String senden */ if(senden(sd, buffer) < 0) { perror("senden"); ende(-1); } }
void str_senden(int sd, char topic[MAXLEN], char data[MAXLEN], int rc) /* baut einen String (string = "topic data") und sendet ihn an den Server */ { char buffer[MAXLEN]; *(data+rc-1) = '\0'; /* String erstellen */ strncpy(buffer, topic, MAXLEN); strncat(buffer, data, MAXLEN - strlen(data) - 2); strncat(buffer, "\n", MAXLEN - strlen(buffer) - 1); /* String senden */ if (senden(sd, buffer) < 0) { perror("senden"); ende(-1); } }
/* Empfangen einer Zeile über einen Deskriptor * Rückgabe: Zeichenanzahl > 0 / 0 bei EOF / -1 bei Fehler */ int empfangen(int in, char *buffer, int maxlen) { int rc; rc = readline(in, buffer, (unsigned int) maxlen-1); if (rc <= 0) { /* Fehler oder EOF */ if (rc < 0) /* Fehler -> Ausgabe */ perror("read"); return rc; } *(buffer+rc) = (char) 0; /* String erstellen */ if (strcasecmp(buffer, "quit\n") == 0) { /* Fehlerfunktion */ ok(sd); ende(1); } return rc; }
int main(int argc, char* argv[]) { printf("Bitte warten, waehrend SpaceCraft geladen wird\n"); if(load()) { printf("Es trat ein Fehler bei load auf, das Programm wird beendet!\n"); return -1; } if(EnGameLoop(move, render)) { printf("Fehler in der GameLoop\n"); return -1; } // * */ ende(); printf("Auf wiedersehen ;)\n"); return 42; }
void teamnamen_eingeben(int gruppe) { int i; char buffer [MAXIMALE_LAENGE_MANNSCHAFTSNAME]; printf("Anzahl der Mannschaften in Gruppe %i: ", gruppe+1); scanf("%d", &mannschaften[gruppe]); if (mannschaften[gruppe]>MAXIMALE_ANZAHL_TEAMS_PRO_GRUPPE) { printf("Fehler: Es koennen maximal %d Teams pro Gruppe eingegeben werden!\n",MAXIMALE_ANZAHL_TEAMS_PRO_GRUPPE); ende(); } fprintf(f, "---gruppe%d---\n", gruppe+1); for (i=0; i<mannschaften[gruppe]; ++i) { printf(" Team %d: ", i+1); scanf("%s", &buffer); if (existiert_teamname(buffer)) { --i; printf(" Fehler: Der Mannschaftsname existiert bereits\n"); continue; } strcpy(teams[gruppe][i], buffer); fprintf(f, "%s\n", buffer); } printf("\n"); }
StreckeScene::StreckeScene(const std::vector<std::unique_ptr<Strecke>>& strecken, Visualisierung& visualisierung, QObject *parent) : QGraphicsScene(parent) { this->setItemIndexMethod(QGraphicsScene::NoIndex); size_t anzahlSegmente = 0, anzahlStreckenelemente = 0; // Berechne UTM-Referenzpunkt als Mittelwert der Strecken-Referenzpunkte double utmRefWe = 0.0; double utmRefNs = 0.0; for (const auto& strecke : strecken) { if (strecke->UTM) { utmRefWe += strecke->UTM->UTM_WE / static_cast<double>(strecken.size()); utmRefNs += strecke->UTM->UTM_NS / static_cast<double>(strecken.size()); } } this->m_utmRefPunkt.UTM_WE = static_cast<int>(utmRefWe); this->m_utmRefPunkt.UTM_NS = static_cast<int>(utmRefNs); std::unique_ptr<Segmentierer> segmentierer = visualisierung.segmentierer(); const auto richtungen_zusi2 = { StreckenelementRichtung::Norm }; const auto richtungen_zusi3 = { StreckenelementRichtung::Norm, StreckenelementRichtung::Gegen }; for (const std::unique_ptr<Strecke>& strecke : strecken) { const UTM strecke_utm = (strecke->UTM ? *strecke->UTM : UTM()); const auto utm_dx = 1000 * (strecke_utm.UTM_WE - this->m_utmRefPunkt.UTM_WE); const auto utm_dy = 1000 * (strecke_utm.UTM_NS - this->m_utmRefPunkt.UTM_NS); // Die Betriebsstellen werden pro Streckenmodul beschriftet, da manche Betriebsstellennamen // (z.B. Sbk-Bezeichnungen) in mehreren Modulen vorkommen und dann falsch platziert wuerden. std::unordered_map<std::string, QRectF> betriebsstellenKoordinaten; bool istZusi2 = false; auto richtungen = istZusi2 ? richtungen_zusi2 : richtungen_zusi3; float offset = (segmentierer->beideRichtungen() || istZusi2) ? 0.49f : 0.0f; for (const auto& streckenelement : strecke->children_StrElement) { if (streckenelement) { anzahlStreckenelemente++; for (StreckenelementRichtung richtung : richtungen) { StreckenelementUndRichtung elementRichtung { streckenelement.get(), richtung }; // streckenelement->richtung(richtung); // Streckenelement-Segmente if (segmentierer->istSegmentStart(elementRichtung)) { auto item = std::make_unique<StreckensegmentItem>(elementRichtung, *segmentierer, offset, nullptr); auto startNr = streckenelement->Nr; auto endeNr = item->ende()->Nr; // Fuer Zusi-3-Strecken wird jedes Segment doppelt gefunden (einmal von jedem Ende). // Manche Visualisierungen sind nicht richtungsspezifisch und brauchen daher nur eines davon. // Behalte nur die Segmente, deren Endelement eine groessere Nummer hat als das Startelement. // (Fuer 1-Element-Segmente behalte dasjenige, das in Normrichtung beginnt). if (istZusi2 || segmentierer->beideRichtungen() || endeNr > startNr || (endeNr == startNr && elementRichtung.getRichtung() == StreckenelementRichtung::Norm)) { // Zusi 3: x = Ost, y = Nord visualisierung.setzeDarstellung(*item); item->moveBy(utm_dx, utm_dy); this->addItem(item.release()); anzahlSegmente++; } } // Signale const auto& richtungsInfo = elementRichtung.richtungsInfo(); if (richtungsInfo.has_value()) { const auto& signal = richtungsInfo->Signal; if (signal && !signal->Signalname.empty() && (istZusi2 || (static_cast<SignalTyp>(signal->SignalTyp) != SignalTyp::Weiche && static_cast<SignalTyp>(signal->SignalTyp) != SignalTyp::Unbestimmt && static_cast<SignalTyp>(signal->SignalTyp) != SignalTyp::Sonstiges && static_cast<SignalTyp>(signal->SignalTyp) != SignalTyp::Bahnuebergang))) { Vec3 vec = elementRichtung.endpunkt() - elementRichtung.gegenrichtung().endpunkt(); float phi = atan2(-vec.Y, vec.X); QColor farbe = Qt::red; switch (static_cast<SignalTyp>(signal->SignalTyp)) { case SignalTyp::Vorsignal: farbe = Qt::darkGreen; break; case SignalTyp::Gleissperre: case SignalTyp::Rangiersignal: farbe = Qt::blue; break; default: break; } auto si = std::make_unique<DreieckItem>(phi, QString::fromUtf8(signal->Signalname.data(), signal->Signalname.size()), farbe); string tooltip = signal->NameBetriebsstelle + " " + signal->Signalname; if (!signal->Stellwerk.empty()) { tooltip += "\n[" + signal->Stellwerk + "]"; } si->setToolTip(QString::fromUtf8(tooltip.data(), tooltip.size())); QPointF pos(elementRichtung.endpunkt().X, elementRichtung.endpunkt().Y); si->setPos(pos); si->moveBy(utm_dx, utm_dy); this->addItem(si.release()); if (static_cast<SignalTyp>(signal->SignalTyp) != SignalTyp::Vorsignal && !signal->NameBetriebsstelle.empty()) { if (betriebsstellenKoordinaten.find(signal->NameBetriebsstelle) == betriebsstellenKoordinaten.end()) { betriebsstellenKoordinaten[signal->NameBetriebsstelle] = QRectF(pos, pos); } else { QRectF& r = betriebsstellenKoordinaten[signal->NameBetriebsstelle]; // TODO somehow QRect::unite does not work if (pos.x() < r.left()) { r.setLeft(pos.x()); } if (pos.x() > r.right()) { r.setRight(pos.x()); } if (pos.y() > r.bottom()) { r.setBottom(pos.y()); } if (pos.y() < r.top()) { r.setTop(pos.y()); } } } } } } } } const auto elementRichtung = [&strecke](const ReferenzElement& refpunkt) -> StreckenelementUndRichtung { if ((refpunkt.StrElement < 0) || (static_cast<size_t>(refpunkt.StrElement) >= strecke->children_StrElement.size())) { return { nullptr, static_cast<StreckenelementRichtung>(refpunkt.StrNorm) }; } else { return { strecke->children_StrElement[refpunkt.StrElement].get(), static_cast<StreckenelementRichtung>(refpunkt.StrNorm) }; } }; // TODO refpunkt->elementRichtung() for (const auto& refpunkt : strecke->children_ReferenzElemente) { if (!refpunkt || !elementRichtung(*refpunkt).getStreckenelement()) continue; if (static_cast<ReferenzpunktTyp>(refpunkt->RefTyp) == ReferenzpunktTyp::Aufgleispunkt) { Vec3 vec = elementRichtung(*refpunkt).endpunkt() - elementRichtung(*refpunkt).gegenrichtung().endpunkt(); qreal phi = atan2(-vec.Y, vec.X); assert(refpunkt->Info.data() != nullptr); auto si = std::make_unique<DreieckItem>(phi, QString::fromUtf8(refpunkt->Info.data(), refpunkt->Info.size()), Qt::magenta); si->setPos(elementRichtung(*refpunkt).endpunkt().X, elementRichtung(*refpunkt).endpunkt().Y); si->moveBy(utm_dx, utm_dy); this->addItem(si.release()); } } for (const auto& p : betriebsstellenKoordinaten) { std::string betriebsstelle = p.first; #if 0 auto ri = this->addRect(p.second); ri->moveBy(1000 * (strecke->utmPunkt.UTM_WE - this->m_utmRefPunkt.UTM_WE), 1000 * (strecke->utmPunkt.UTM_NS - this->m_utmRefPunkt.UTM_NS)); #endif auto ti = std::unique_ptr<Label>(new Label(QString::fromUtf8(betriebsstelle.data(), betriebsstelle.size()))); ti->setAlignment(Qt::AlignCenter | Qt::AlignHCenter); ti->setPos((p.second.left() + p.second.right()) / 2.0, (p.second.top() + p.second.bottom()) / 2.0); ti->moveBy(utm_dx, utm_dy); ti->setFlag(QGraphicsItem::ItemIgnoresTransformations); ti->setPen(QPen(Qt::black)); ti->setBrush(QBrush(Qt::black)); this->addItem(ti.release()); } } // TODO: Kreise ohne jegliche Weichen werden nicht als Segmente erkannt. qDebug() << anzahlSegmente << "Segmente für" << anzahlStreckenelemente << "Streckenelemente"; }
/* hier wird der Rundenablauf gesteuert */ int runde(int sd) { int rc, err; /* Returncodes/Fehler */ int erg[3]; /* Ergebnis des Ratens, z.B.: {1234,3,1} */ int rundenende; /* Wenn 1 wird Abfrage für neue Runde aufgerufen */ char buffer[MAXLEN]; rundenende = 0; printf("Errate die Geheimzahl von %s!\n", opponentplayer); printf("Gib deinen Versuch ein (4 unterschiedliche Ziffern): "); while(1) { fd_set bereit; FD_ZERO(&bereit); FD_SET(0, &bereit); FD_SET(sd, &bereit); /* Eingabe vom Nutzer oder Nachricht vom Server abwarten */ rc = select(MAX(0, sd) + 1, &bereit, NULL, NULL, NULL); if (rc < 0) { if (errno == EINTR) continue; perror("select"); ende(SIGTERM); } if (rc == 0) continue; if (FD_ISSET(sd, &bereit)) { if (empfangen(sd, buffer, MAXLEN) <= 0) { perror("empfangen"); ende(-1); } /* es kommt quit */ if (strcasecmp(buffer, "quit\n") == 0) { perror("Der Server ist nicht mehr erreichbar!"); ende(-1); } /* überprüfen ob Gewonnen/Verloren/Remis */ if (strcasecmp(buffer, "gewonnen\n") == 0) { printf("\n\nYuppieh - Du hast gewonnen!\n"); printf("=========== \n"); /* mit OK bestätigen */ ok(sd); } if (strcasecmp(buffer, "verloren\n") == 0) { printf("\n\nSchade - Du hast verloren...\n"); printf("=========== \n"); /* mit OK bestätigen */ ok(sd); } if (strcasecmp(buffer, "remis\n") == 0) { printf("\n\nUnentschieden - Beide haben es gleichzeitig geschafft!\n"); printf("=========== \n"); /* mit OK bestätigen */ ok(sd); } /* Gegenspielerversuch empfangen -> Ausgabe */ if (strncasecmp(buffer, "versuch:", 8) == 0) { /* Gegenspielerversuch auslesen */ rc = sscanf(buffer, "%*s %d", &erg[0]); if (rc != 1) { perror("versuch empfangen"); ende(-1); } /* Ausgabe des Versuchs */ printf("\t%s hat geraten: %04d ", opponentplayer, erg[0]); printf("(Deine Geheimzahl lautet: %s)\n", secret); /* mit "OK" bestaetigen */ ok(sd); } /* Das Ergebnis des eigenen Versuchs empfangen */ if (strncasecmp(buffer, "ergebnis:", 9) == 0) { /* Zahlen auslesen */ rc = sscanf(buffer, "%*s %d %d %d", &erg[0], &erg[1], &erg[2]); if (rc != 3) { perror("ergebnis"); ende(-1); } /* Ausgabe des Ergebnis vom Server */ printf("\tDein Versuch %04d ergab (richtig: Anzahl / Stelle): %d / %d\n", erg[0], erg[1], erg[2]); /* mit "OK" bestaetigen */ ok(sd); printf("\nGib deinen neuen Versuch ein (4 unterschiedliche Ziffern): "); } /* Abfrage für neue Runde empfangen */ if (strcasecmp(buffer, "noch einmal?\n") == 0) { printf("Willst du noch einmal spielen (j/n)? "); /* eine Runde hat ein Ergebnis */ rundenende = 1; /* mit "OK" bestaetigen */ ok(sd); } continue; } /* stdin ist bereit */ if (FD_ISSET(0, &bereit)) { rc = readline(0, buffer, MAXLEN); if (rc < 0) { perror("readline"); ende(-1); } if (rc > 5){ printf("Gib deinen Versuch ein (4 unterschiedliche Ziffern): "); continue; } *(buffer+rc) = '\0'; /* bei Rundenende wird (j/n) als Eingabe erwartet */ if (rundenende) { if (strncasecmp(buffer, "j\n", 2) == 0) { /* String senden */ if (senden(sd, "bereit\n") < 0) { perror("senden"); ende(-1); } /* Auf anderen Spieler warten */ waitforserverreply(sd, 1, buffer); printf("\n======> Eine neue Runde beginnt <======\n\n"); /* gebe 1 zurück um eine weitere Runde zu starten */ return 1; } if (strncasecmp(buffer, "n\n", 2) == 0) { /* gebe 0 zurück um keine weitere Runde zu starten */ return 0; } else { printf("Falsche Eingabe, erwarte (j/n)\n"); continue; } } /* eingelesene Zahl auf Richtigkeit */ err = checknumber(buffer); if (err == 1) { /* Bei Fehler neu einlesen */ printf("Gib deinen Versuch ein (4 unterschiedliche Ziffern): "); err = 0; continue; } /* Bei korrekter Zahl -> an den Server senden */ else { /* Geheimzahl senden */ str_senden(sd, "ZAHL: ", buffer, 5); /* Antwort abwarten */ waitforserverreply(sd, 1, buffer); if (strcasecmp(buffer, "ok\n") != 0) { perror("ok"); ende(-1); } } } } /* Zahl-einlesen-Schleife */ } /* Raterunde - Ende */
void mastermind(int sd) /* Die Spiel-Funktion */ { int rc; int err; int gamerounds; char buffer[MAXLEN]; /*char tmp[MAXLEN];*/ /* stdout ungepuffert, damit write(1, ..) und printf() genutzt werden können */ setbuf(stdout, NULL); /* Warten auf den Start der Kommunikation */ waitforserverreply(sd, 0, buffer); /* Auf Fehler überprüfen */ if (strcasecmp(buffer, "HALLO\n") != 0) { perror("Hallo"); ende(-1); } /* Hallo mit ok bestätigen */ ok(sd); /* Spielernamen einlesen beginnt: */ printf("Gib deinen Spielernamen ein!\n"); printf("Dein Spielername: "); while(1) { fd_set bereit; FD_ZERO(&bereit); FD_SET(0, &bereit); FD_SET(sd, &bereit); /* Prüfen ob Socket oder stdin bereit sind */ rc = select(MAX(0, sd) + 1, &bereit, NULL, NULL, NULL); /* Auf Fehler überprüfen */ if (rc < 0) { if (errno == EINTR) continue; perror("select"); ende(-1); } /* While-Schleife fortsetzen falls nicht bereit war */ if (rc == 0) continue; /* Es kam eine Nachricht vom Server (Socket) */ if (FD_ISSET(sd, &bereit)) { /* empfangen (kann auch EOF sein!) */ if (empfangen(sd, buffer, MAXLEN) <= 0) { /* Server ist nicht mehr erreichbar - Ende */ perror("empfangen"); ende(-1); } continue; } /* Der Spieler hat etwas eingegeben und mit '\n' bestätigt */ if (FD_ISSET(0, &bereit)) { /* von Eingabe lesen */ rc = readline(0, buffer, MAXLEN-1); /* Fehler -> Ende */ if (rc < 0) { perror("readline"); ende(-1); } /* String erstellen */ *(buffer+rc) = '\0'; /* Prüfen ob gültiger Name eingegeben wurde */ /* Prüfen auf Länge */ if (strlen(buffer) == 1) { printf("Bitte einen gültigen Spielernamen angeben: "); /* Nochmal einlesen */ continue; } /* Spielernamen sichern */ strcpy(playername, buffer); /* Namen senden */ str_senden(sd, "NAME: ", playername, rc); /* die Einleseschleife beenden */ break; } }/*-----Ende Spielernamen-Einlese-Schleife-----*/ /* Warten auf "OK" vom Server */ waitforserverreply(sd, 0, buffer); /* Überprüfen ob wirklich "OK" empfangen wurde */ if (strcasecmp(buffer, "ok\n") != 0) { perror("OK"); ende(-1); } /* Warten auf Gegenspielername */ waitforserverreply(sd, 0, buffer); /* Auf Fehler überprüfen */ if (strncasecmp(buffer, "name: ", 6) != 0) { perror("name"); ende(-1); } /* mit "OK" bestätigen */ ok(sd); /* Sichern des Gegenspielernamens */ strcpy(opponentplayer, &buffer[6]); /* Newline vom Namen entfernen */ opponentplayer[strlen(opponentplayer) - 1] = '\0'; /* Namen des Gegenspielers ausgeben */ printf("Dein Gegenspieler nennt sich: %s.", opponentplayer); /* Warten auf Anzahl der Runden */ waitforserverreply(sd, 0, buffer); /* Auf Fehler überprüfen */ if (strncasecmp(buffer, "runden: ", 6) != 0) { perror("Runden"); ende(-1); } /* mit "OK" bestaetigen */ ok(sd); /* Speichern der Rundenzahl */ if (sscanf(buffer, "%*s %d", &gamerounds) < 1) { perror("not rounds"); ende(-1); } /* dem Spieler die Rundenanzahl mitteilen */ printf("Es sind maximal %d Runden vereinbart.\n\n", gamerounds); /* Runden beginnt */ while(1) { /* Geheimzahl einlesen */ printf("Gib deine Geheimzahl ein (4 unterschiedliche Ziffern): "); while(1) { fd_set bereit; FD_ZERO(&bereit); FD_SET(0, &bereit); FD_SET(sd, &bereit); rc = select(MAX(0, sd) + 1, &bereit, NULL, NULL, NULL); if (rc < 0) { if (errno == EINTR) continue; perror("select"); ende(-1); } if (rc == 0) continue; if (FD_ISSET(sd, &bereit)) { if (empfangen(sd, buffer, MAXLEN) <= 0) { perror("empfangen"); ende(-1); } continue; } if (FD_ISSET(0, &bereit)) { rc = readline(0, secret, MAXLEN); if (rc < 0) { perror("readline"); ende(-1); } *(secret+rc) = '\0'; /* Eingelesenen String auf korrekte Zahl prüfem */ err = checknumber(secret); if (err == 1) { printf("Gib deine Geheimzahl ein (4 unterschiedliche Ziffern): "); err = 0; /* Bei Fehler neu einlesen */ continue; } /* Geheimzahl senden */ str_senden(sd, "GEHEIMZAHL: ", secret, rc); /* Einles Schleife beenden */ break; } } /* Geheimzahl-Einlesen-Schleife Ende */ waitforserverreply(sd, 1, buffer); if (strcasecmp(buffer, "ok\n") != 0) { perror("ok"); ende(-1); } /* Warte auf Nachricht um Raterunde zu starten */ waitforserverreply(sd, 0, buffer); if (strcasecmp(buffer, "start\n") != 0) { perror("start"); ende(-1); } /* "Start" mit "OK" bestaetigen */ ok(sd); printf("Es kann los gehen!\n"); printf("==================\n\n"); /* Raterunde beginnt */ if (!runde(sd)) break; } /* Spiel wird beendet wenn runde nicht 1 zurückgibt */ /* Mastermindfunktion Ende -> zurück zur Main-Funktion -> Programmende */ return; }
/*------------------------------------------------------------------------------------*/ void waitforserverreply(int sd, int spieler, char *buffer) { int rc; int timeout; int abbruch; fd_set bereit; timeout = 0; abbruch = 0; while(1) { struct timeval zeit; FD_ZERO(&bereit); FD_SET( 0, &bereit); FD_SET( sd, &bereit); zeit.tv_sec = 1; zeit.tv_usec = 0; rc = select(MAX(0,sd) + 1, &bereit, NULL, NULL, &zeit); if (rc < 0) { if (errno != EINTR) { perror("select"); ende(-1); //ende(SIGTERM); } continue; } if (rc == 0) { if(spieler) { /* wird ein einziges Mal aufgerufen */ printf("Warte auf %s!\n", opponentplayer); spieler = 0; } write(1, "-", 1); timeout++; if(timeout > TIMEOUT) { printf("\nDer Server hat nach %d Sekunden immernoch nicht geantwortet!\n",TIMEOUT); printf("Abbrechen/aufgeben? (j/n): "); timeout = 0; abbruch = 1; } continue; } if (FD_ISSET(0, &bereit)) { /* stdin auslesen */ rc = readline(0, buffer, MAXLEN); if (rc < 0) { perror("readline"); ende(-1); //ende(SIGTERM); } /* String erstellen */ *(buffer+rc) = (char) 0; if(abbruch) { abbruch = 0; if (strcasecmp(buffer, "j\n") == 0) { /* Fehlerfunktion */ ende(0); } } else { /* Tue nichts, Eingabe ist nicht erlaubt */ printf("Bitte warten!\n"); } continue; } if (FD_ISSET(sd, &bereit)) { if(empfangen(sd, buffer, MAXLEN) <= 0) { perror("empfangen"); ende(-1); } break; } } printf("\n"); }
void waitforserverreply(int sd, int spieler, char *buffer) /* wartet auf Nachricht vom Server und empfängt diese anschließend */ { int rc; int timeout; /* verschtrichende Zeit */ int abbruch; fd_set bereit; timeout = 0; abbruch = 0; while(1) { struct timeval zeit; FD_ZERO(&bereit); FD_SET(0, &bereit); FD_SET(sd, &bereit); zeit.tv_sec = 1; zeit.tv_usec = 0; rc = select(MAX(0, sd) + 1, &bereit, NULL, NULL, &zeit); if (rc < 0) { if (errno != EINTR) { perror("select"); ende(-1); } continue; } if (rc == 0) { if (spieler) { /* wird ein einziges Mal aufgerufen wenn spieler 1 gesetzt wurde */ printf("Warte auf %s!\n", opponentplayer); spieler = 0; } /* Ausgabe eines Wartezeichens (einmal pro Sekunde) */ write(1, "-", 1); timeout++; /* Bei zu langer Wartezeit dem Spieler dies mitteilen */ if (timeout > TIMEOUT) { printf("\nDer Server hat nach %d Sekunden immernoch nicht geantwortet!\n", TIMEOUT); printf("Abbrechen/aufgeben? (j/n): "); timeout = 0; abbruch = 1; } continue; } if (FD_ISSET(0, &bereit)) { /* stdin auslesen */ rc = readline(0, buffer, MAXLEN); if (rc < 0) { perror("readline"); ende(-1); } /* String erstellen */ *(buffer+rc) = '\0'; if (abbruch) { abbruch = 0; if (strcasecmp(buffer, "j\n") == 0) { /* Fehlerfunktion */ ende(0); } } else { /* Tue nichts, Eingabe ist nicht erlaubt */ printf("Bitte warten!\n"); } continue; } /* Server hat etwas gesendet */ if (FD_ISSET(sd, &bereit)) { if (empfangen(sd, buffer, MAXLEN) <= 0) { perror("empfangen"); ende(-1); } break; } } printf("\n"); }
/*------------------------------------------------------------------------------------*/ void mastermind(int sd) /* Die Spiel-Funktion */ { int rc; int err; int gamerounds; char buffer[MAXLEN]; /*char tmp[MAXLEN];*/ /* stdout ungepuffert, damit write(1,..) und printf() genutzt werden können */ setbuf(stdout, NULL); /* Warten auf den Start der Kommunikation */ waitforserverreply(sd,0, buffer); /* Auf Fehler überprüfen */ if (strcasecmp(buffer, "HALLO\n") != 0) { perror("No Hallo"); ende(-1); } /* Hallo mit ok bestätigen */ ok(sd); printf("Gib deinen Spielernamen ein!\n"); printf("Dein Spielername: "); while(1) { fd_set bereit; FD_ZERO(&bereit); FD_SET( 0, &bereit); FD_SET(sd, &bereit); rc = select(MAX( 0, sd) + 1 , &bereit, NULL, NULL, NULL); if (rc < 0) { if (errno == EINTR) continue; perror("select"); ende(SIGTERM); } if (rc == 0) continue; /* Es kam eine Nachricht vom Server */ if (FD_ISSET(sd, &bereit)) { /* Erst einmal empfangen (kann auch EOF sein!) */ if (empfangen( sd, buffer, MAXLEN) <= 0) { /* Server ist nicht mehr erreichbar - Ende der Kommunikation */ perror("empfangen"); ende(-1); } continue; } /* Der Spieler hat etwas eingegeben und mit '\n' bestätigt */ if (FD_ISSET(0, &bereit)) { /* von Eingabe lesen */ rc = readline(0, buffer, MAXLEN-1); /* Fehler -> Ausgabe */ if (rc < 0) { perror("readline"); ende(-1); } /* String erstellen */ *(buffer+rc) = (char) 0; /* Prüfen ob gültiger Name eingegeben wurde */ /* Prüfen auf Länge */ if (strlen(buffer) == 1) { printf("Bitte einen gültigen Spielernamen angeben: "); continue; } /* Spielernamen sichern */ strcpy(playername, buffer); /* Namen senden */ str_senden(sd, "NAME: ", playername, rc); /* die Einleseschleife beenden */ break; } }/*-----Ende Spielernamen-Einlese-Schleife-----*/ /* Warten auf "OK" vom Server */ waitforserverreply(sd,0, buffer); /* Überprüfen ob wirklich "OK" empfangen wurde */ if (strcasecmp(buffer, "ok\n") != 0) { perror("not OK"); ende(-1); } /* Warten auf Gegenspielername */ waitforserverreply(sd,0, buffer); /* Auf Fehler überprüfen */ if (strncasecmp(buffer, "name:", 5) != 0) { perror("not name"); ende(-1); } /* mit "OK" bestätigen */ ok(sd); /* Sichern des Gegenspielernamens */ strcpy(opponentplayer, &buffer[6]); opponentplayer[strlen(opponentplayer) - 1] = '\0'; /* Namen des Gegenspielers ausgeben */ printf("Dein Gegenspieler nennt sich: %s.", opponentplayer); /* Warten auf Anzahl der Runden */ waitforserverreply(sd,0, buffer); /* Auf Fehler überprüfen */ if (strncasecmp(buffer, "runden:", 5) != 0) { perror("not rounds"); ende(-1); } /* mit "OK" bestaetigen */ ok(sd); /* Speichern der Rundenzahl */ if( sscanf(buffer, "%*s %d", &gamerounds) < 1) { perror("not rounds"); ende(-1); } /* dem Spieler die Rundenanzahl mitteilen */ printf("Es sind maximal %d Runden vereinbart.\n\n", gamerounds); /* Geheimzahl einlesen */ while(1) { printf("Gib deine Geheimzahl ein (4 unterschiedliche Ziffern): "); while(1) { /* Variable um einen Fehler zu behandeln */ fd_set bereit; FD_ZERO(&bereit); FD_SET( 0, &bereit); FD_SET(sd, &bereit); rc = select(MAX( 0, sd) + 1 , &bereit, NULL, NULL, NULL); if (rc < 0) { if (errno == EINTR) continue; perror("select"); ende(SIGTERM); } if (rc == 0) continue; if (FD_ISSET(sd, &bereit)) { /* Erst einmal empfangen (kann auch EOF sein!) */ if (empfangen( sd, buffer, MAXLEN) <= 0) { /* Server ist nicht mehr erreichbar - Ende der Kommunikation */ perror("empfangen"); ende(-1); } continue; } if (FD_ISSET(0, &bereit)) { rc = readline(0, secret, MAXLEN); if (rc < 0) { /* Fehler -> Ausgabe */ perror("readline"); ende(SIGTERM); } *(secret+rc) = (char) 0; /* String erstellen */ err = checknumber(secret); if(err == 1) { printf("Gib deine Geheimzahl ein (4 unterschiedliche Ziffern): "); err = 0; continue; } if (strcasecmp(secret, "exit\n") == 0) continue; if (strcasecmp(secret, "quit\n") == 0) continue; if (strcasecmp(secret, "ok\n") == 0) continue; if (strcasecmp(secret, "\n") == 0) continue; if (strcasecmp(secret, "\0") == 0) continue; /* Geheimzahl senden */ str_senden(sd, "GEHEIMZAHL: ", secret, rc); break; } } waitforserverreply(sd,1, buffer); if (strcasecmp(buffer, "ok\n") != 0) { perror("not ok"); ende(-1); } waitforserverreply(sd,0,buffer); if (strcasecmp(buffer, "start\n") != 0) { perror("not start"); ende(-1); } /* mit "OK" bestaetigen */ ok(sd); printf("Es kann los gehen!\n"); printf("==================\n\n"); if(!runde(sd)) break; } return; }
/* hier wird der Rundenablauf gesteuert */ int runde(int sd) { int rc, err; int erg[3]; int rundenende; char buffer[MAXLEN]; rundenende = 0; printf("Errate die Geheimzahl von %s!\n", opponentplayer); printf("Gib deinen Versuch ein (4 unterschiedliche Ziffern): "); while(1) { fd_set bereit; FD_ZERO(&bereit); FD_SET( 0, &bereit); FD_SET(sd, &bereit); /* Eingabe vom Nutzer oder Nachricht vom Server abwarten */ rc = select(MAX( 0, sd) + 1 , &bereit, NULL, NULL, NULL); if (rc < 0) { if (errno == EINTR) continue; perror("select"); ende(SIGTERM); } if (rc == 0) continue; /* Es kommt eine Nachricht vom Server */ if (FD_ISSET(sd, &bereit)) { if (empfangen( sd, buffer, MAXLEN) <= 0) { /* Server ist nicht mehr erreichbar - Ende der Kommunikation */ perror("empfangen"); ende(-1); } /* es kommt quit */ if (strcasecmp(buffer, "quit\n") == 0) { perror("Der Server ist nicht mehr erreichbar!"); ende(SIGTERM); } /* überprüfen ob Gewonnen/Verloren/Remis */ if (strcasecmp(buffer, "gewonnen\n") == 0) { printf("\n\nYuppieh - Du hast gewonnen!\n"); printf("===========\n"); ok(sd); } if (strcasecmp(buffer, "verloren\n") == 0) { printf("\n\nSchade - Du hast verloren...\n"); printf("===========\n"); ok(sd); } if (strcasecmp(buffer, "remis\n") == 0) { printf("\n\nUnentschieden - Beide haben es gleichzeitig geschafft!\n"); printf("===========\n"); ok(sd); } if (strncasecmp(buffer, "versuch:", 8) == 0) { //printf("vom Server: \"%s\"\n",buffer); rc = sscanf(buffer, "%*s %d", &erg[0]); if(rc != 1) { perror("versuch empfangen"); ende(-1); } printf("\t%s hat geraten: %04d ", opponentplayer, erg[0]); printf("(Deine Geheimzahl lautet: %s)\n", secret); /* mit "OK" bestaetigen */ ok(sd); } if (strncasecmp(buffer, "ergebnis:", 9) == 0) { //printf("vom Server: \"%s\"\n",buffer); rc = sscanf(buffer, "%*s %d %d %d", &erg[0], &erg[1], &erg[2]); if(rc != 3) { perror("ergebnis"); ende(-1); } printf("\tDein Versuch %04d ergab (richtig: Anzahl / Stelle): %d / %d\n", erg[0], erg[1], erg[2]); /* mit "OK" bestaetigen */ ok(sd); printf("\nGib deinen neuen Versuch ein (4 unterschiedliche Ziffern): "); } if (strcasecmp(buffer, "noch einmal?\n") == 0) { printf("Willst du noch einmal spielen (j/n)? "); rundenende = 1; /* mit "OK" bestaetigen */ ok(sd); } continue; } if (FD_ISSET(0, &bereit)) { rc = readline(0, buffer, MAXLEN); if (rc < 0) { /* Fehler -> Ausgabe */ perror("readline"); ende(-1); } if (rc > 5){ printf("Gib deinen Versuch ein (4 unterschiedliche Ziffern): "); continue; } *(buffer+rc) = '\0'; if(rundenende) { if (strncasecmp(buffer, "j\n", 2) == 0) { /* String senden */ if(senden(sd, "bereit\n") < 0) { perror("senden"); ende(-1); } waitforserverreply(sd,1,buffer); /* gebe 1 zurück um eine weitere Runde zu starten */ return 1; } if (strncasecmp(buffer, "n\n", 2) == 0) { /* gebe 0 zurück um keine weitere Runde zu starten */ return 0; } else { printf("Falsche Eingabe, erwarte (j/n)\n"); continue; } } err = checknumber(buffer); if(err == 1) { printf("Gib deinen Versuch ein (4 unterschiedliche Ziffern): "); err = 0; continue; } else { /* Geheimzahl senden */ str_senden(sd, "ZAHL: ", buffer, 5); waitforserverreply(sd,1, buffer); if (strcasecmp(buffer, "ok\n") != 0) { perror("client: not ok"); ende(-1); } } } } }
/*------------------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { struct sockaddr_in adresse; /* Internet-Adress-Struktur */ u_short port = 12345; /* Default Serverportnr.: 12345 */ struct hostent *server; /* Zeiger für Server-Informationn */ char *servername; int rc; int optchar; /* Was soll passieren wenn SIGINT eintrifft? */ if (signal(SIGINT, abfangen) == SIG_ERR) { perror("SIGINT"); ende(-1); } if (signal(SIGQUIT, SIG_IGN) == SIG_ERR) { perror("SIGQUIT"); ende(-1); } if (signal(SIGPIPE, ende) == SIG_ERR) { perror("SIGPIPE"); ende(-1); } opterr = 0; while(optchar = getopt(argc, argv, "p:"), optchar != -1) { switch(optchar) { case 'p': /* Portnummer setzen */ rc = sscanf(optarg, "%hu", &port); if (rc != 1) usage(argv[0]); break; default: usage(argv[0]); } } if (optind >= argc) { fprintf(stderr, "Hostname bitte übergeben\n"); perror("Hostname"); usage(argv[0]); } servername = argv[optind]; sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) { perror("socket"); ende(-1); } printf("Server: %s\n", servername); printf("Port : %hu\n", port); printf("=======\n"); /* Adress-Struktur belegen */ memset(&adresse, 0, sizeof(adresse)); adresse.sin_family = AF_INET; adresse.sin_port = htons(port); server = gethostbyname(servername); if (server == NULL) { perror(servername); ende(-1); } adresse.sin_addr = *(struct in_addr *) server->h_addr; if (connect(sd, (struct sockaddr *)&adresse, sizeof(adresse)) < 0) { perror("connect"); usage(argv[0]); ende(-1); } /* starten des Spiels Mastermind */ mastermind(sd); /* nach Spielende Socket schließen */ close(sd); /* Main-Funktion Ende */ printf("Spielende\n"); return 0; }