חצי האי האיברי, שהיה ברובו תחת שליטה קרתגית, הוחזק על ידי אחיו של חניבעל (עזרובעל ומאגו), אך הצבא הרומי, תחת פיקודו של המצביא המוכשר פובליוס קורנליוס סקיפיו, הצליח להשתלט בהדרגה על שטח היספניה לאחר שהנחיל סדרת תבוסות לצבאות הקרתגנים (210-206 לפנה"ס). לאחר השלמת גירוש הכוחות הקרתגנים מהיספניה, הציע סקיפיו אפריקאנוס להביא לסיום המלחמה נגד קרתגו באמצעות פלישה לצפון אפריקה, ויצירת איום ישיר על העיר קרתגו. על אף ההתנגדות הזהירה של הסנאט, העניקה אספת העם לסקיפיו אישור לגייס ולאמן צבא לצורך הגשמת תוכניתו.
בתחילה סקיפיו נהג בזהירות ותגבר את כוחותיו מעריקים מקומיים. לאחר שמסיניסה החליף את סיפאקס (הפרו-קרתגי) כמלך הנומידים, סקיפיו הרגיש, שביכולתו להסתכן בקרב והתחיל להטיל אימה על קרתגו עצמה.
הסנט הקרתגי קרא לחניבעל לחזור מאיטליה עם צבאו המורכב מאזרחים מקומיים וותיקי המלחמה מאיטליה. צבאו של חניבעל היה מורכב מ-40,000 רגלים ו-3,000 פרשים. צבאו של סקיפיו (עם בוא התגבורת מהנסיך מסיניסה) היה מורכב מ-34,000 רגלים ו-9,000 פרשים.
היערכות הכוחות.
חיל הרגלים הוצב במרכז מערך הצבא הרומי ואורגן בשלושה הקווים/הדרגים המסורתיים, בעוד הפרשים הוצבו בשני האגפים, כאשר הפרשים האיטלקיים בפיקוד לאלוס באגף השמאלי והפרשים הנומידיים בפיקוד מסיניסה באגף הימני. אולם בניגוד למקובל, סקיפיו לא פרס את המאניפולים של הלגיונות שלו בתבנית "לוח השחמט" המקובלת (כאשר המאניפולים בקווים העורפיים מוצבים מאחרי הרווחים שבין המונופולים הקדמיים), אלא בשורה עורפית, בזה אחר זה, כך שיצרו מעברים פנויים בתוך המערך הרומי. הרווחים בתוך המערך מולאו על ידי הוליטים, רגלים קלים שנכללו מכל מאניפול. האחרונים נועדו לפנות את המעברים, ולתפוס מחסה מאחרי הרגלים הכבדים יותר, ברגע שפילי המלחמה של חניבעל יפתחו בהסתערות, לתעל אותם לתוך המעברים, ולהטריד אותם מהאגפים.
חניבעל פרס את כל הפילים שלו (שמונים במספר) מלפנים בקו הראשון. מאחריהם נפרסו הרגלים שלו, גם הם בשלושה קווים. בקו הראשון הוצבו שכירי חרב מגאליה ומליגוריה, וקלעים מהאיים הבלאריים, כ-12 אלף לוחמים שגויסו על ידי מאגון, אחיו של חניבעל. בקו השני הוצבו רגלים בעלי חימוש כבד יותר, רובם טירונים שגויסו מקרתגו ומלוב, ואילו בקו האחרון הוחזקו ותיקי המלחמה מאיטליה, שרידי צבאו המקורי של חניבעל, 15-24 אלף לוחמים מנוסים. ההיסטוריון ליוויוס כתב, שצבאו של חניבעל כלל גם 4000 לוחמים מוקדוניים, רגלים כבדים שהמלך פיליפוס ממוקדון שלח לעזרת קרתגו, אך חוקרים מודרניים נוטים לראות בטענה זו תעמולה רומית שקרית. הפרשים הוצבו בשני האגפים, כאשר 2000 פרשים נומידיים, שנותרו נאמנים לקרתגו, הוצבו באגף השמאלי של הצבא הקרתגני, ואילו הפרשים הקרתגניים הוצבו באגף הימני, מול הפרשים האיטלקיים .
חניבעל קיווה, שהפרשים שלו יצליחו למשוך את הפרשים העדיפים של יריבו משדה הקרב, וכך יבטלו את היתרון העיקרי של סקיפיו על צבאו. כוחות הרגלים של חניבעל, שנהנו מעדיפות מספרית ניכרת על יריביהם, היו אמורים להביס את הלגיונות הרומיים בסיוע הלם ההסתערות של הפילים.
מהלך הקרב.
חניבעל פתח את הקרב, כצפוי, בהסתערות חזיתית של הפילים שלו על מרכז המערך הרומאי, אך מהלך זה פעל כבומרנג, וגרם לו יותר נזק מתועלת. סקיפיו, שצפה מראש את המהלך של יריבו, קידם את פני הפילים בתרועת חצוצרות וקרנות מלחמה, שהבהילו את הפילים, וגרמו לחלקם לפנות לאחור, ולשבש את המערך של הפרשים הנומידיים באגף השמאלי של הצבא הקרתגני. הפילים שהמשיכו בהסתערות גרמו נזק ניכר לרגלים הקלים, שהוצבו לפני המערך הרומי העיקרי, וחלקם לא הספיקו להימלט, אך לאחר מכן תועלו להתקדם במעברים, שסקיפיו פתח במערך צבאו, ולא גרמו נזק רב. הם נפגעו מכידונים וקלעים למיניהם, שהוטלו עליהם משני העברים, יצאו מכלל שליטה וחלקם סבו לאחור ותקפו במנוסתם את הפרשים הקרתגנים באגף הימני של חניבעל. הפילים שנמלטו משדה הקרב הבהילו את הסוסים, ושיבשו את הסדר בקרב הפרשים. כוחות הפרשים של סקיפיו, בפיקוד לאליוס ומסיניסה, ניצלו את הבלבול והמהומה בשורות יריביהם, כדי לתקוף ולהביס את שתי כנפות הפרשים של חניבעל שניצבו מולם, ולהניס אותם משדה הקרב.
לאחר כישלון התקפת הפילים התקדמו כוחות הרגלים של הצבאות היריבים זה לקראת זה. חניבעל קידם את שני הקווים הראשונים של צבאו, אך שמר את הקו השלישי בעתודה, במרחק כ-200 מטר מאחריהם. הקו הראשון של הלגיונות הרומיים (האסטאטים) פתח בהתקפה על קו הרגלים הראשון של חניבעל. בתחילה הצליחו השכירים הגאליים והליגוריים של חניבעל לבלום את התקדמות הלגיונות, והקרב היה שקול, אולם כאשר סקיפיו תיגבר את הקו הראשון שלו במאניפולים של חיילים מהקו השני (פרינקיפים), החלו החיילים הרומיים להדוף לאחור את יריביהם בעצם כוח משקלם והמשמעת העדיפה שלהם. לבסוף נשברה התנגדות הלוחמים בקו הקרתגני הראשון, שבניגוד לרומאים לא קיבלו סיוע מהלוחמים שהוצבו מאחריהם, בקו השני. הם נמלטו לעורף בתקווה למצוא מקלט מאחרי הקו הקרתגני השני, שהורכב מרגלים כבדים יותר, שגויסו מקרתגו ומלוב, אך החיילים בקו השני לא איפשרו להם לעבור דרכם, מחשש שאם יפתחו את שורותיהם, הדבר ישבש את מערכם ויאפשר לרומאים הרודפים להבקיע דרכם. חלק מהנמלטים הנואשים ניסו להבקיע לעצמם דרך בלחימה, והשאר פנו ימינה ושמאלה בניסיון לעקוף את הקו הקרתגני.
תסריט דומה חזר על עצמו כאשר הלגיונות הרומיים תקפו את הקו הקרתגני השני. בתחילה הצליחו הקרתגנים להדוף לאחור את הקו הרומי הראשון, שמערכו השתבש מכיוון ששדה הקרב היה זרוע בגופות וחלקלק מדם, אך סקיפיו שוב תיגבר אותו בכוחות מהקו השני, ומכיוון שהמערך הרומי היה פחות עמוק מהמערך הקרתגני, והיה פרוס על פני חזית רחבה יותר, כוחותיו הצליחו לאגף אותו משני עבריו. החיילים בקו הקרתגני השני נשברו ופנו לנוס, אך החיילים בקו השלישי והאחרון שוב מנעו מהם מעבר דרך שורותיהם, אילצו אותם להימלט ימינה ושמאלה, וחלקם הצטרפו אל האגפים של הקו הקרתגני השלישי והגדילו את רוחב החזית שלו.
בשלב זה של הקרב עצר סקיפיו את התקדמות כוחותיו, הסיג לאחור את האסטאטים שלו, וארגן מחדש את הלגיונות בדרג אחד, שנפרס על חזית רחבה יותר, הן כדי למנוע מחניבעל לאגף את כוחותיו והן כדי לנצל בצורה מיטבית את כלי הנשק שבראשותם (חניתות ההטלה). הוא רצה להרוויח זמן, כדי לאפשר לפרשיו לחזור לשדה הקרב מהמרדף אחרי פרשיו של חניבעל. לפי פוליביוס, בשלב זה הכוחות של הצדדים היריבים היו שווים פחות או יותר בגודלם, אך חניבעל נהנה מיתרון משמעותי, משום שהכוחות בקו השלישי שלו הורכבו מחיילים מנוסים ורעננים, שעדיין לא היו מעורבים בקרב, בעוד שמהלגיונות הרומיים רק החיילים הוותיקים ביותר (הטריארים, כ-600 חיילים בכל לגיון), שהוחזקו בקו השלישי, עדיין לא הוטלו למערכה.
למרות השמדת שני הקווים הראשונים של הצבא הקרתגני, נבלמו הרומאים על ידי הלוחמים המנוסים והמצוידים היטב, שהרכיבו את הקו השלישי של חניבעל. התחולל קרב קשה ועקוב מדם שנמשך זמן רב, וכוחותיו של חניבעל החלו להשיג יתרון קל על כוחותיו של סקיפיו (שניסיון האיגוף שלהם נכשל). פוליביוס כתב : "שעה ארוכה היו תוצאות ההתמודדות מוטלות בספק. האנשים נפלו במקום עומדם מתוך עוז החלטה, עד שהגיעו מסיניסה וליליוס כשלוחים משמים ברגע הנכון". הפרשים הנומידיים של מסיניסה והפרשים האיטלקיים של ליליוס חזרו בזמן מהמרדף שלהם אחרי הפרשים הקרתגנים, ותקפו את עורפם של הרגלים של חניבעל. כפי שאירע בקרב קאנאי, התקפת הפרשים הכריעה את הקרב. חייליו הוותיקים של חניבעל, שכותרו והותקפו במקביל מהחזית ומהעורף, המשיכו להילחם בעוז עד הסוף, ורובם נהרגו במקומם. פרשיו של סקיפיו ניהלו מרדף נמרץ בשטח מישורי פתוח אחרי שרידי הצבא הקרתגני, שניסו להימלט משדה הקרב, והרגו או שבו את רובם.
לפי דברי פוליביוס וליוויוס, תבוסתו של חניבעל הייתה שלמה, ורוב צבאו הושמד בשדה הקרב. כ-20 אלף חיילים קרתגנים נהרגו, וכ-18 אלף נפלו בשבי. אבדות הצבא הרומאי היו קלות יחסית, 1500-2000 הרוגים וכ-4000 פצועים. חניבעל עצמו הצליח להימלט משדה הקרב עם קבוצת מלווים קטנה. הוא הבין עתה שהמלחמה אבודה, ושכנע את נכבדי קרתגו לקבל את תנאי הכניעה של הרומאים.
תוצאות הקרב.
זמן קצר לאחר התבוסה בקרב זאמה קיבל הסנאט הקרתגני את תנאי הכניעה שהכתיב להם סקיפיו, ובכך באה לקיצה המלחמה הפונית השנייה לאחר 17 שנות לחימה.
תנאי הסכם הכניעה היו נדיבים למדי, בהתחשב במצב ובנזקים שגרם חניבעל לרומא במהלך המלחמה:
הסעיף האחרון היווה את העילה לפרוץ המלחמה הפונית השלישית שהביאה סוף לקרתגו בידיו של פובליוס קורנליוס סקיפיו איימיליאנוס (נכדו המאומץ של סקיפיו אפריקאנוס) כחמישים שנים מקץ המלחמה השנייה.
פובליוס קורנליוס סקיפיו קיבל את התואר 'אפריקאנוס' על המערכה באפריקה, שהביאה לסיום המלחמה נגד קרתגו.
סיכום ולקחים.
למרות תבוסתו המוחצת בקרב זאמה, ההיסטוריונים ליוויוס ופוליביוס, שכתביהם משמשים מקור עיקרי לתולדות המלחמה הפונית השנייה, חלקו לחניבעל שבחים רבים על הדרך בה ניהל את הקרב (אולי במטרה להאדיר את ניצחונו של סקיפיו במערכה נגדו) וכתבו שאף מצביא אחר לא היה מסוגל לנהל את הקרב בצורה טובה יותר. אולם בחינה של מהלכי הקרב על פי תיאורם, מעלה מספר סימני שאלה ביחס לדרך ניהול הקרב על ידי חניבעל.